面向对象

面向对象
 
    什么是面向对象
        面向对象编程(Object Oriented Programming,OOP编程),是一种计算机编程架构。它将真实世界的各种复杂的关系,抽象为一个一个的对象,然后由对象之间的分工与合作,完成对真实世界的模拟。注:抽象是从众多事物中抽取出来的共同的、本质性的特征,而舍弃其非本质的特征。
    重用性
        针对相同功能可以重复使用的功能
    灵活性
        针对差异性的做出调整与适配
    扩展性
        针对功能的变化做出添加或删除的改进
    封装性
        封装是一种信息隐蔽技术,使得用户只能见到对象的外特性,而对象的内特性对用户是隐蔽的。封装的目的在于把对象的设计者和对象的使用者分开,使用者不必知晓行为的实现的细节,只须用设计者提供的消息来访问该对象
    继承性
        复用原有的一些功能,并且可以扩展和修改。
    多态性
        对象根据所接受的消息而做出动作,同一消息为不同的对象接受时可以产生不同的行动。
    属性
        描述状态
    方法
        描述行为
    程序中
        变量就是属性,函数就是方法
    在面向对象编程中,是通过类来创建对象的,类相当于模具。根据传递的数据来创建对象,并且可以重复的创建对象。
    在ES6之前,是没有类的概念的,不过可以通过构造函数来代替类进行创建对象。
    构造函数和普通函数并没有多大的差别,只是调用的时候需要通过new来实现,构造函数中的this指针指向构造函数创建出来的对象,并且具备隐式返回操作
        注:定义类一般首字母大写,所以定义构造函数也要求首字母需要大写。
    1.继承
        1.继承和UML图
            1.类的继承
                1.父类和子类
                    例如动物类是父类,则狗就是子类,父类又可以称为基类。子类是无法继承的。
                2.方法重写
                    父类的方法有时候不适用于子类,所有原生js的对象都继承于object,比如将数组toString,并用逗号隔开,相当于子类将父类的方法重写了
            2.UML表示类
                父类Animal,子类dog,子类cat
            3.UML表示继承
                子类dog继承父类,子类cat继承父类
        2.构造函数继承
            Person构造函数一般用大写字母开头,提示创建者需要new来新建一个对象
                function Person (name,age){
                    this.name = name;
                    this.age = age;
                    this.sayHello = function(){
                        alert(this.name);
                    }
                }

 

            我们一般不把方法放到基类上,而是把方法放到原型上
                function Person (name,age){
                    this.name = name;
                    this.age = age;
                }
                Person.prototype.sayHello = function(){
                    alert(this.name);
                }

 

            1.创建了一个Person对象
            2.将this指针指向了这个对象
            3.执行构造函数代码
            4.将构造函数返回
                 var p = new Person(); 
                apply call
            一个函数通过普通的方法去调用Person();this指针指向根元素window,如果通过某个对象的方法去调用,这个this指针指向这个方法前面的对象.
                function Student (name,age,id){
                    Person.apply(this,[name,age]);//this指针就不会指向window,而是指向Student.
                    Person.call(this,name,age);//也可以使用call,call是将参数独立传入,而apply则使用数组的方式。
                    this.id = id;
                    this.sayHello = Person.aplly.sayHello()
                    this.study = function(){
                        alert(this.id + "is studying");
                    }
                }

 

        3.原型链继承
            1.原型prototype
            2.基于原型的继承
                1.Object.create();
                2.原型继承图示。
                3.原型链
                    只要创建了函数,prototype就会自动生成在函数内。prototype指向一个对象,这个对象就是Person prototype
                    name age sayHello都创建在Person prototype对象上。
                    Person                   Person prototype   <--------------- p
                    prototype--------》      name                                _proto_
                                                     age
                                                     sayHello()

 

                    1.创建了一个Person对象
                    2.创建了一个属性,双向线_proto_,它指向了构造函数的原型
                    3.将this指针指向了这个对象
                    4.执行构造函数代码
                    5.将构造函数返回
                        function Person(){}
                        Person.prototype.name = "sdf";
                        Person.prototype.age = 11;
                        Person.prototype.sayHello = function (){
                            alert(this.name);
                        }
                        var p = new Person();
                        p.sayHello();

 

                    当访问一个对象属性的时候,首先在对象本身上进行查找,如果找到这个属性,则返回,停止查找,如果没有找到,则到原型上找,双向线__proto__上查找。
                        function Student(){}
                    创建一个中间对象__proto__,Studentprototype指向了中间对象__proto__,中间对象__proto__指向Person prototype,改变中间对象的值不会对Person prototype有所影响。
                         Student.prototype = Object.create(Person.prototype); 
                    创建的s对象的双向线__proto__指向了原型指向的对象中间对象__proto__
                        var s = new Student;
                        s.sayHello();

 

                    假使我们访问一个方法,s.study();双向线__proto__会一层一层去找指向的对象,有则返回,没有则查到NULL值为止返回。这种查找方式是比较慢的,它需要一层层的去找,不如变量快,因为变量是直接在地址上查找。
        4.混合继承
            1.构造函数+原型链
                构造函数没办法继承原型上的属性和方法的,如果是纯的原型的继承,没有参数的传递,相当于我们创建的对象都是一模一样的,将两个方法混合起来,就叫做混合继承,也叫组成继承。
            2.属性的继承
            3.方法的继承
                我们一般把属性放在对象上,把方法放到原型上。这样子类不会被属性所改变,也保证了,函数的方法可以被所有的proto共享。
                function Person (name,age){
                    this.name = name;
                    this.age = age;
                }
                Person.prototype.sayHello = function(){
                    alert(this.name);
                }
                function Student (name,age,id){
                    Person.apply(this,[name,age]);//this指针就不会指向window,而是指向Student.
                    Person.call(this,name,age);//也可以使用call,call是将参数独立传入,而apply则使用数组的方式。
                    this.id = id;
                }
                Student.prototype = object.create(Person.prototype);
                Student.prototype.study = function(){
                        alert(this.id + "is studying");}

 

    2.闭包
        1.什么是闭包
        2.闭包的原理
        3.闭包的应用
posted @ 2019-10-08 13:46  solaris-wwf  阅读(132)  评论(0)    收藏  举报