面向对象3

本文详细讲解了JavaScript中的面向对象编程,包括封装的实现(构造函数封装和闭包),各种继承方式(类式继承、构造函数式继承、组合继承和原型式继承),以及多态的概念和应用。通过实例展示了如何使用这些概念在实际开发中操作类和对象。
摘要由CSDN通过智能技术生成

JS面向对象-封装,继承,多态。

1.封装

1.1构造函数封装

  • 通俗的来讲就是说我们有一些秘密不想让人知道。我们就需要通过私有化变量和私有化方法的形式,将函数封装起来。这样的话外界不能访问函数内部的私有化变量私有化方法;如果你有一些想让大家知道的东西,你就可以通过 this 在创建的属性看作是对象共有的属性和对象共有方法。这样别人就能知道你的公共的东西,不止如此你还可以访问到类或者对象自身的私有属性和私有方法。
    // 封装前
    var Book=function(id,name,price){
        this.id=id;
        this.name=name;
        this.price=price;
    }
    // 封装后
    var Book=function(id,name,price){
        // 私有属性
        var num=1;
        // 私有方法
        function checkId();
        var bookname='';

        // 特权方法
        this.getName=function(){
            return bookname;
        };
        this.getPrice=function(){};
        this.setName=function(){
            bookname=name
        };
        this.setPrice=function(){};
        // 对象公有属性
        this.id=id;
        // 对象公有方法
        this.aaa=function(){};
        // 构造器
        this.setName(name);
        this.setPrice(price);
    }
    var  b=new Book(1,'Javascrpit 面向对象',8.9);

    console.log(b.num);//undefined
    console.log(b.id);// id的值
    console.log(b.setName('aaaaa'));

1.2闭包实现封装

  • 闭包是有权限访问另外一个函数作用域中变量的函数。也就是在一个函数内部创建另外一个函数。
  • 闭包呢,是在一个函数内部创建一个新的函数。并且在函数的外部调用内部创建的新函数作用域内的变量或函数所构成的闭合区间。称之为闭包。
    (function(){
        // 静态私有变量
        var bookNum=0;
        // 静态私有方法
        function checkBook(name){
            // 检查书的语言
        }

        // 创建书籍类
        function Book(newId,newNeme,newPrice){
            // 私有变量
            var name,price;
            // 私有方法
            var setNemt=function(name_){
                name=`${name_}`
            }
            var setPrice=function(price_){
                price=Number(price)2;
            }
            setNemt(newName);
            setNemt(newPrice);
            bookNum++;
            if(bookNum>3){
               throw new Error('我们仅出版3本书')
            }
            // 特权方法
            this.getName=function(){
                return name;
            };
            this.getPrice=function(){
                return price;
            };
            // 公有属性
            this.id=newId;
        }
        Book.prototype={
            // 静态公有成员属性
            isBookType:'历史书'
        }
        // 返回整个类别
            return Book;
    })();

2.继承

  • 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。

2.1类

  • 每一个类大致有三部分:
    • 1.是构造函数内的,是提供实例化对象赋值用的。
    • 2.构造函数外部的直接通过点儿语法添加的。这是供类使用的。实例化对象是访问不到的。
    • 3.类的原型当中,实例化对象可以通过其原型链简单的访问到也是提供所有实例化对象共有的。

2.1类式继承

    function SuperClass() {
    this.superValue = true;
    //   this.getSuperValue = function() {
    //     return this.superValue;
    //   };
    // 不在构造函数内部
    }
    // var a=new SuperClass();
    // a.superValue;
    // a.getSuperValue
    // 为父类添加共有方法
    SuperClass.prototype.getSuperValue = function() {
    return this.superValue;
    };

    // 声明子类
    function SubClass() {
    this.subValue = false;
    }

    // 需求: 实例化子类对象的时候,子类对象 包含父类对象中的一些属性
       // 超类 父类  基类
        function User() {
            this.type='人';
        }
        User.prototype = {
            sayType: function () {
                return this.type;
            }
        }
        // 学生  子类
        /@class
        // name:姓名
        // age:年龄
        // score:123
        /
        function Student(score) {  
            //    Student独有的特性
            this.score = score;
        }
        Student.prototype=new User();
        /
          @class
         // 老师:  子类
         // name:姓名
         // age:年龄
        // xs:薪水
         /
        function Teacher( xs) {
            
            //    Teacher独有的特性
            this.xs = xs;
        }

        Teacher.prototype=new User();
  • 缺点:就是一个子类的实例原型。从父类构造函数当中继承来的共有属性就会直接影响到其他子类。
    function SuperClass(){
    this.books=['js','jquery','html'];
    }
    function SubClass(){}
    SubClass.prototype=new SuperClass();
    var a= new SubClass();
    var  b=new SubClass();
  • 额外的知识点:InstancesOf。是通过对象的prototype。来确定这个对象是否是某个类的实例,而不关心对象与类的自身结构。

2.2 构造函数式继承

  • 构造函数式继承是通过在子类的构造函数作用环境中执行一次父类的构造函数来去实现。
    // 父类声明
    function User(name){
        this.name=name;
        this.books=['js','jquery','html']
    }

    User.prototype.showBooks=function(){
        console.log(this.books);
    }

    // 声明子类
    function Student(name){
        User.call(this.books);
        this.score=score;
    }

    var s1=new Student('佚名',99);
    var s1=new Student('佚名',22);
    s2.books.push("金瓶梅");
    // s2.books
    // ["js", "jquery", "html", "金瓶梅"]
    // s1.books
    // ["js", "jquery", "html"]
  • 构造函数式继承,的关键在与call函数和apply函数
  • 缺点:子类继承了父类的所有属性,却没办法继承父类的原型属性。

2.3 组合继承

  • 组合式的继承:类式继承+构造函数式继承
    // 父类声明
    function User(name){
        this.name=name;
        this.books=['a','b','c']
    }

    // 父类的原型公有方法
    User.prototype.getname=function(){
        console.log(this.name);
    }
    // 声明子类
    function Student(name){
        // 构造函数继承 继承了父类当中的元素属性
        User.call(this.name);
        this.score=score;
    }

    // 类式继承
    Student.prototype=new User();
    Student.prototype.getScore=function(){
        console.log(this.score);
    }
  • 子类的实例当中。更改父类继承下来的引用属性。引用类型的属性。比如说那里边儿的 books。根本不会影响到其他的实例对象。并且子类实例化过程当中又能将参数传递到父类的构造函数里面。并且系成了父类的原型方法。

2.4 原型式继承

  • 原型式继承。跟类是继承一样。父类对象当中的那个 books 中的值的这个类型的属性时会被复制一遍。引用类型的属性是被共有的。
    // 原型式继承
    function inheritObject(obj){
        // 声明了一个过渡函数对象
        function F(){}
        // 过渡对象的原型继承父对象
        F.prototype=obj;
        return new F();
    }

    var book={
        name:'jacasctipt 面向对象',
        istyoe:['css3 入门','html5 页面编程']
    }

    var newBook=inheritObject(book);
    newBook.name='jquery Book';
    newBook.istyoe.push('ajax Book');

    var otherBook=inheritObject(book);
    otherBook.name='php Book';
    otherBook.istyoe.push('mysql Book');

2.5 寄生式的继承

  • 在一个函数内部找一个过渡对象来去实现继承,并且返回新对象。
  • 通过在一个函数内的过渡对象。中实现继承并返回新对象的这种方式。称之为寄生式的继承.
  • 寄生就像寄生虫一样。寄托于某个对象的内部生长。就是对原型继承的第二次封装。并且在这第二次封装的过程当中,对继承的对象进行了一些扩展。这样新的新创建的对象不仅仅有父类的属性和方法。而且还添加了新的属性和方法。
// 父类
    function Book() {
        // this.name
    }
    // 父类实例
    var book = {
        name: "javascript 面向对象",
        istype: ["css3入门", "html5 页面编程"]
    };
    // 原型式继承
    function inheritObject(obj) {
        // 声明一个过渡函数对象
        function F() {}
        // 过渡对象的原型继承父对象
        F.prototype = obj;
        return new F();
    }

    function createBook(obj, score) {
        var o = new inheritObject(obj);
        o.score = score;
        o.getName = function() {
            console.log(o.name);
        }
        // 返回扩展后 的新对象
        return o;
    }

2.6 寄生组合式继承

  • 寄生组合式继承:寄生式继承+构造函数式继承
    // 原型式继承
    function inheritObject(obj) {
        // 声明一个过渡函数对象
        function F() {}
        // 过渡对象的原型继承父对象
        F.prototype = obj;
        return new F();
    }
    /
      寄生式继承  继承原型
      传递参数  subClass,子类
      传递参数  superClass,父类
      /
    funtion inheritPrototype(subClass, superClass) {
        // 复制一份父类的原型副本保存在变量中
        var superPrototype = inheritObject(superClass.prototype)
            // 修正因为重写子类原型导致子类的 constructor属性被修改
            // superPrototype.constructor=subClass;
            // 设置子类的原型
        subClass.prototype = superPrototype;
    }

    // 定义父类
    function SuperClass(name) {
        this.name = name;
        this.books = ['js', 'html', 'css'];
    }
    // 父类原型方法
    SuperClass.prototype.getName = function() {
        console.log(this.name);
    }

    //定义子类
    function SubClass(name, score) {
        SuperClass.call(this, name);
        // 子类新属性
        this.score = score;
    }

    // 寄生式继承父类原型
    inheritPrototype(SubClass, SuperClass);
    //子类新增原型方法
    SubClass.prototype.getScore = function() {
        console.log(this.score);
    }

3. 多态

  • 多态就是通过对传递的参数判断来去执行不同的逻辑。就可以实现一种多态处理机制。我们通过这个多态调用一个运算方式,根据不同的参数做不同的运算。
    function Add(){
        // 无参数算法
        function zero(){
            return 0;
        }
    }

    // 一个参数
    function one(num){
        return num;
    }

     // 两个参数
    function two(num1,num2){
        return num1+num2;
    }

    // 两个以上的参数算法
    function more(nums){
        var result=0;
        for(var i=0;i<nums.length;i++){
            result+=nums[i];
        }
    }

    this.a=function (){
        // 动态参数列表
        var arg=arguments;
        len=arg.length;
        switch (len) {
            // 无参数
            case 0:
                return zero();
            // 有一个参数
            case 1:
                return one(arguments[0]);
            // 有两个参数
            case 2:
                return two(arguments[0], arguments[1]);
            default:
                return more(arguments);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lx610321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值