面向对象中的继承

本文探讨JavaScript中类式继承、构造函数继承、组合继承、原型继承以及多态的应用,包括寄生式和终极继承策略,揭示面向对象核心概念的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在函数(类)的内部通过this(函数内部自带的一个变量)变量添加属性或者方法来实现对类添加属性或者方法。

通过this添加属性、方法是在当前对象上添加,JavaScript是一种基于原型prototype的语言,每创建一个对象时,都会有一个原型prototype用于指向它继承的属性、方法。

然而通过prototype继承的方法并不是对象本身的,在使用这些方法时,是通过prototype一层一层查找到的。

var book = function(id,bookname,price){
            this.id = id;
            this.bookname = bookname;
            this.price = price;
        }
        book.prototype.display = function(){
            //....
        }

        book.prototype = {
            display:function(){
                //执行代码块
            }
        }

        var bookA = new book(01,'javascript',100)
        console.log(bookA.bookname)
var Book = function(title,time,type){
           //判断执行的this是否是当前对象
           if (this instanceof Book) {
               this.title = title;
               this.name = name;
               this.type = type;
           }else{
               return new Book(title,time,type);
           }
       }

       var bookA =  Book("CSS3",'2015','css');
       console.log(bookA.type)

继承

类的原型对象就是给类原型添加公有方法、属性,但是类不能直接访问这些属性和方法,必须通过原型prototype来访问。

新建的对象复制了父类的构造函数内的属性和方法,并且把原型指向父类的原型对象。这样新建的对象就拥有了父类的原型和方法,该新建的对象可以直接访问到父类原型上的属性和方法。这就是继承。

类式继承

function  SuperClass(){
          this.superValue = true;
      }

      SuperClass.prototype.getSuperValue = function(){
          return this.superValue;
      }

      function SubClass(){
          this.subValue = false;
      }

      SubClass.prototype = new SuperClass();

      SubClass.prototype.getSubValue = function(){
          return this.subValue
      }

      var val = new SubClass();
      console.log(val.getSuperValue()); //true
      console.log(val.getSubValue()); //false

使用instanceof来判断前者是否后者(类)的实例。

构造函数继承

function S(id){
          this.books = ['javascript',"html","css"];

          this.id = id;
      }

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

      //子类
      function Sub(id){
          S.call(this,id);
      }
      var instance1 = new Sub(10);
      instance1.books.push("javascript");
      console.log(instance1.books)
      console.log(instance1.id)

类式继承是通过子类的原型prototype对父类实例化来实现的,构造函数式继承是通过在子类的构造函数作用环境中执行一次父类的构造函数来实现。

组合继承

function SuperClass(name){
          this.name = name;

          this.books = ["javascript","html","css"];
      }

      SuperClass.prototype.getName = function(){
          console.log(this.name);
      }

      function subClass(name,time){
          SuperClass.call(this,name);
          this.time = time;
      }

      subClass.prototype = new SuperClass();
      subClass.prototype.getName = function(){
          console.log(this.time)
      }



      var bookB = new subClass("java",'2015');
      bookB.books.push("CSS3");

      console.log(bookB);
      console.log(bookB.books);

原型继承

function inheritObject(o){
         function F(){}
         F.prototype = o;
         return new F();
     }

     var book = {
         name:"javscript",
         alikeBook:["css","HTML5"]
     };
     var newBook = inheritObject(book);

     newBook.name = "vue";

     newBook.alikeBook.push("ajax");

     console.log(newBook.alikeBook);

寄生式继承

就是对原型式继承进行封装,在封装过程中对继承的对象进行拓展。

var bookA = {
    name: "js",
    alikeBook: ['html', 'css']
}
function createBook(obj) {
    //通过原型继承的方式来创建新的对象
    var o = new inheritObject(obj);

    //拓展新对象
    o.getName = function () {
        console.log(name)
    }
    return o;
}

寄生组合式继承(终极者继承)

是寄生式继承和构造函数式继承的组合

/**
 * 寄生组合式继承
 * 终极继承者
 * 参数  subClass 子类
 * 参数 superClass 父类
 */

 function inheritPrototype(subClass,superClass){
        
        var p = inheritObject(superClass.prototype);

        //防止在重写子类原型导致子类的constructor属性被修改
        p.constructor = subClass;

        //设置子类原型
        subClass.prototype = p;
 }

多继承

JavaScript中的继承是依赖于prototype链来实现的,只有一条链。在理论上是不能实现继承多个父类。但是可以通过一些技巧来继承多个多个对象的属性类实现类似的多继承

/**
  * 类似的多继承
  * 单继承 属性复制
  * 浅复制过程,只能复制值类型的属性,对于引用类型就无能为力。
  */

  var extend = function(target,source){
      //遍历源对象中的属性
      for(var property in source){
          target[property] = source[property];
      }
      return target;
  };
  
/**
   * 多继承 属性复制
   * 把传入的多个对象属性复制到源对象中,
   */

   var mix = function(){
       var i = 1,
           len = arguments.length,
           target = arguments[0],
           arg;
        
           //遍历被继承的对象
           for(;i < len;i++){
               //缓存当前的对象
               arg = arguments[i];

               //遍历被继承对象的属性
               for(var property in arg){
                   target[property] = arg[property];
               }
           }
        return  target
   };

   Object.prototype.mix = function(){
       var i = 0 ,
           len = arguments.length,
           arg;
        for(;i<len;i++){
            for(var property in arg){
                this[property] = arg[property]
            }
        }
   }

多态——多种调用方式

同一个方法多种调用方式,但是必须要对传入的参数做判断而实现多种调用方式。如:

function add(){
     var arg = arguments,
        len = arg.length;

        switch(len){
            case 0:
                  return 10;
            case 1:
                  return 10+arg[0];
            case 2:
                  return arg[0]+arg[1]                
        }
 }

console.log(add()); //10
console.log(add(90)); //100
console.log(add(25,79)) //104

封装和继承是面向对象的两个重要特性,继承就是对源对象的封装,过程中创建私有属性、私有方法、特权方法,共性属性,共有方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

读心悦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值