面向?qū)ο箨P(guān)鍵知識(shí)點(diǎn)匯總

面向?qū)ο箨P(guān)鍵知識(shí)點(diǎn)匯總

先來了解一些基礎(chǔ)概念,才能更好的理解知識(shí)。

對(duì)象的定義

ECMA-262把對(duì)象定義為:“無序?qū)傩缘募?,其屬性可以包含基本值、?duì)象或者函數(shù)。

數(shù)據(jù)屬性

4個(gè)特性

  • [[Configurable]]:默認(rèn)true 表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性。
  • [[Enumerable]]: 默認(rèn)true 表示能否通過for-in 循環(huán)返回屬性
  • [[Writable]]: 默認(rèn)true 表示能否修改屬性的值。
  • [[Value]]: 默認(rèn)值為undefined, 屬性的數(shù)據(jù)值,讀和寫入都在這個(gè)位置。

以上屬性一般通過Object.defineProperty()方法來修改,接受三個(gè)參數(shù):屬性所在的對(duì)象、屬性的名字和一個(gè)描述符對(duì)象。其中描述符就是上面四個(gè)特性。

訪問器屬性

4個(gè)特性

  • [[Configurable]]:默認(rèn)true 表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性。
  • [[Enumerable]]: 默認(rèn)true 表示能否通過for-in 循環(huán)返回屬性
  • 訪問器屬性不能直接定義,必須使用 Object.defineProperty()來定義。
定義多個(gè)屬性 以及讀取屬性的特性

Object.defineProperties()方法

在調(diào)用 Object.defineProperty()方法時(shí),如果不指定,configurable、enumerable 和
writable 特性的默認(rèn)值都是 false。

Object.getOwnPropertyDescriptor()方法

接受兩個(gè)參數(shù):屬性所在的對(duì)象和要讀取其描述符的屬性名稱。

var book = {};
Object.defineProperties(book, {
 _year: {
    value: 2004
 },
 edition: {
    value: 1
 },
 year: {
    get: function(){
    return this._year;
 },
 set: function(newValue){
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
 }
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); //2004
alert(descriptor.configurable); //false 
alert(typeof descriptor.get); //"undefined"

var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value); //undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get); //"function" 
工廠模式

用函數(shù)來封裝以特定接口創(chuàng)建對(duì)象的細(xì)節(jié)

function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function () {
        alert(this.name);
    };
    return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor"); 

作用:解決了創(chuàng)建多個(gè)相似對(duì)象的問題
缺陷:沒有解決對(duì)象識(shí)別的問題(即怎么知道一個(gè)對(duì)象的類型)

構(gòu)造函數(shù)模式

new 一個(gè)構(gòu)造函數(shù)通常會(huì)經(jīng)歷一下四個(gè)步驟

  • 創(chuàng)建一個(gè)新對(duì)象
  • 將構(gòu)造函數(shù)的作用域賦給新對(duì)象(因此this就指向了這個(gè)新對(duì)象)
  • 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性)
  • 返回新對(duì)象

由于構(gòu)造函數(shù)內(nèi)部定義的屬性和方法,通過實(shí)例化后都有自己的作用域鏈和辨識(shí)符解析。為了讓屬性和函數(shù)能夠更好的公用,這時(shí)候原型模式就要登場(chǎng)了。

isPrototypeOf()的作用

當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例后,該實(shí)例的內(nèi)部包含一個(gè)指針(內(nèi)部屬性),指向構(gòu)造函數(shù)的原型對(duì)象。ECMA-262中管這個(gè)指針叫[[Prototype]]。在腳本中沒有標(biāo)準(zhǔn)的方式訪問[[Prototype]],但瀏覽器(Firefox,Safari,chrome)在每個(gè)對(duì)象上都支持一個(gè)屬性/proto/;我們要知道的是,這個(gè)屬性對(duì)腳本則是完全不可見的。可以通過isPrototypeOf()方法來確定對(duì)象之間是否存在這種關(guān)系。從本質(zhì)上講,如果[[Prototype]]指向調(diào)用isPrototypeOf()方法的對(duì)象(Person.prototype),那么這個(gè)方法就返回true

function Person(){
} 
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
 alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas" 
Person.prototype.isPrototypeOf(person1)//true

ECMAScript 5 增加了一個(gè)新方法 Object.getPrototypeOf(),在所有支持的實(shí)現(xiàn)中,這個(gè)方法返回[[Prototype]]的值。例如

Object.getPrototypeOF(person1) === Person.prototype // true

hasOwnProperty()的使用場(chǎng)景

當(dāng)我們從一個(gè)構(gòu)造函數(shù)實(shí)例一個(gè)對(duì)象后,如果在這個(gè)實(shí)例上創(chuàng)建一個(gè)屬性或者方法,正好與這個(gè)實(shí)例的原型上的屬性或者方法同名,那么訪問時(shí)就會(huì)屏蔽原型上的屬性或者方法。當(dāng)然這樣做不會(huì)修改原型上的屬性或者方法。如果要恢復(fù)指向原型,那么使用delete操作符則可以完全刪除實(shí)例屬性。 使用 hasOwnProperty()方法可以檢測(cè)一個(gè)屬性是存在于實(shí)例中,還是存在于原型中。不要忘記這個(gè)方法是從Object繼承來的,所以只在給定屬性存在于對(duì)象實(shí)例中時(shí),才會(huì)返回true.

in 操作符的作用

in 操作符只要通過對(duì)象能夠訪問到屬性就會(huì)返回true. ,hasOwnProperty()只在屬性存在于實(shí)例中時(shí)才返回 true,因此只要 in 操作符返回 true 而hasOwnProperty()返回 false,就可以確定屬性是原型中的屬性。

function hasPrototypeProperty(object, name){
     return !object.hasOwnProperty(name) && (name in object);
} 
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var person = new Person();
alert(hasPrototypeProperty(person, "name")); //true
person.name = "Greg";
alert(hasPrototypeProperty(person, "name")); //false 

for-in的特殊

在使用 for-in 循環(huán)時(shí),返回的是所有能夠通過對(duì)象訪問的、可枚舉的(enumerated)屬性,其中既包括存在于實(shí)例中的屬性,也包括存在于原型中的屬性。屏蔽了原型中不可枚舉屬性(即將[[Enumerable]]標(biāo)記為 false 的屬性)的實(shí)例屬性也會(huì)在 for-in 循環(huán)中返回,因?yàn)楦鶕?jù)規(guī)定,所有開發(fā)人員定義的屬性都是可枚舉的——只有在 IE8 及更早版本中例外。

Object.keys()

獲取對(duì)象上所有可枚舉的實(shí)例屬性,返回一個(gè)字符串?dāng)?shù)組。
Object.getOwnPropertyNames()
如果是想得到所有的實(shí)例屬性,包括不可枚舉的,就能使用Object.getOwnPropertyNames() 能夠獲取到不可枚舉的constructor屬性。

constructor屬性什么情況下會(huì)指向Object

function Person(){
}
Person.prototype = {
 name : "Nicholas",
 age : 29,
 job: "Software Engineer",
 sayName : function () {
 alert(this.name);
 }
}; 

為了減少重復(fù)代碼,我們經(jīng)常用一個(gè)包含所有屬性和方法的對(duì)象字面量來重寫整個(gè)原型對(duì)象。代碼如上所示。這里會(huì)產(chǎn)生一個(gè)情況,就是constructor屬性不再指向Person。為什么會(huì)這樣呢?我們知道,每創(chuàng)建一個(gè)函數(shù),就會(huì)同時(shí)創(chuàng)建它的prototype對(duì)象,這個(gè)對(duì)象也會(huì)自動(dòng)獲得constructor屬性。而我們上面這樣的寫法,本質(zhì)上完全重寫了默認(rèn)的prototype對(duì)象,因此constructor屬性也就變成了新對(duì)象的constructor屬性(指向Object構(gòu)造函數(shù)),不再指向Person函數(shù)。所以為什么我們用instanceof并不能準(zhǔn)確的判別實(shí)例的構(gòu)造函數(shù)。如下代碼

var p = new Person()
console.log(p instanceof Object)//true
console.log(p instanceof Person)//true
console.log(p.constructor === Person)//false
console.log(p.constructor === Object)//true

有下面兩種方法將constructor設(shè)置回來

function Person(){
}
Person.prototype = {
 constructor : Person,
 name : "Nicholas",
 age : 29,
 job: "Software Engineer",
 sayName : function () {
 alert(this.name);
 }
};

以上這種重設(shè)constructor屬性會(huì)導(dǎo)致它的[[Ennumerable]]特性設(shè)置為true,所以我們可以用下面這種方法;

//重設(shè)構(gòu)造函數(shù),只適用于 ECMAScript 5 兼容的瀏覽器
Object.defineProperty(Person.prototype, "constructor", {
 enumerable: false,
 value: Person
});
組合構(gòu)造函數(shù)模式和原型模式

原型模式的缺點(diǎn)就是在共享時(shí)屬性和方法后,要是修改了內(nèi)容值,那么同一個(gè)構(gòu)造函數(shù)出來的實(shí)例就會(huì)都受到影響。例如下面代碼

function Person(){
}
Person.prototype = {
 constructor: Person,
 friends : ["Shelby", "Court"]
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van"); 
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
alert(person1.friends === person2.friends); //true

所以組合使用構(gòu)造函數(shù)模式與原型模式就是大家普遍用到的方法,我們想要定義自己的屬性和方法,那么就在構(gòu)造函數(shù)中定義即可。例如下面代碼:

function Person(name, age, job){
 this.name = name;
 this.age = age;
 this.job = job;
 this.friends = ["Shelby", "Court"];
}
Person.prototype = {
 constructor : Person,
 sayName : function(){
 alert(this.name);
 }
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true 
什么是動(dòng)態(tài)原型模式

意思就在初始化實(shí)例的時(shí)候就檢測(cè)判斷是否原型中存在你想要的屬性或者方法,要是沒有,就可以在原型上定義你想要的屬性或方法。如一下代碼:

function Person(name, age, job){
 //屬性
 this.name = name;
 this.age = age;
 this.job = job; if (typeof this.sayName != "function"){

 Person.prototype.sayName = function(){
 alert(this.name);
 };

 }
} 
var friend = new Person("Nicholas", 29, "Software Engineer"); 
friend.sayName()
什么是寄生構(gòu)造函數(shù)模式

這個(gè)模式跟工廠模式幾乎是一樣的。通過在一個(gè)構(gòu)造函數(shù)內(nèi)部創(chuàng)建一個(gè)新的對(duì)象(數(shù)組、字符串),然后你可以隨意在這個(gè)定義的新對(duì)象上添加屬性和方法,最后return這個(gè)新的對(duì)象。例如一下代碼:

function SpecialArray(){
 //創(chuàng)建數(shù)組
 var values = new Array();
 //添加值
 values.push.apply(values, arguments);
 //添加方法
 values.toPipedString = function(){
 return this.join("|");
 };

 //返回?cái)?shù)組
 return values;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green" 

這樣做的優(yōu)點(diǎn)是我們可以很輕松在原生對(duì)象上創(chuàng)建一個(gè)自己想要的方法和屬性。但是返回的對(duì)象與構(gòu)造函數(shù)或者與構(gòu)造函數(shù)的原型屬性之間沒有關(guān)系。這樣我們不能通過instanceof操作符確定對(duì)象類型。

什么是穩(wěn)妥構(gòu)造函數(shù)模式

所謂穩(wěn)妥對(duì)象,指的是沒有公共屬性,而且其方法也不引用this對(duì)象。一是新創(chuàng)建對(duì)象的實(shí)例方法不引用this;二是不使用new操作符調(diào)用構(gòu)造函數(shù)。

繼承

什么是原型鏈

我們先來弄懂一句話: 每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型對(duì)象的內(nèi)部指針。這就是相當(dāng)于構(gòu)建一個(gè)原型鏈的基石,整個(gè)原型鏈就是由這樣一個(gè)基石累計(jì)起來。

為什么實(shí)例中很少單獨(dú)使用原型鏈?

主要有下面兩個(gè)原因

  • 引用類型值的原型屬性會(huì)被所有實(shí)例共享
  • 在創(chuàng)建子類型的實(shí)例時(shí),不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。

比如下面的例子中我們實(shí)現(xiàn)簡單的繼承

function Father(){
    this.colors = ["red","blue","green"];
}

function Son(){}

Son.prototype = new Father();

var instance1 = new Son();

instance1.colors.push('black');
console.log(instance1.colors);// red blue,green,black
var instance2 = new Son();
console.log(instance2.colors);// red blue,green,black

上面例子我們可以看見兩個(gè)實(shí)例共享了一個(gè)方法,這是我們不愿意看到的地方,那么有什么方法能夠解決這個(gè)問題呢?

借用構(gòu)造函數(shù)能否解決上面兩個(gè)問題?

什么是借用構(gòu)造函數(shù)? 就是在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型的構(gòu)造函數(shù)。如下面代碼:

function Father(){
    this.colors = ['red','blue','green'];
}
function Son(){
    //繼承 或者使用apply
    Father.call(this)
}

var instance1 = new Son();
instance1.colors.push('black');
console.log(instance1.colors);//red blue,green,black
var instance2 = new Son();
console.log(instance2.colors);// red blue,green

怎么傳遞參數(shù)? 就是在調(diào)用父類構(gòu)造函數(shù)時(shí),傳遞參數(shù)。具體見下面代碼

function Father(name) {

    this.name = name;
}
function Son(){
    Father.call(this,'pan');
    this.age = 28;
}
var instance = new Son()
console.log(instance.name)//pan
console.log(instance.age)//28

但是借用構(gòu)造函數(shù)也用的不多,為什么呢?

  • 方法都在構(gòu)造函數(shù)中定義,函數(shù)復(fù)用就沒有施展的地方了。
  • 而且超類型的原型中定義的方法,對(duì)子類型而言也是不可見的。
組合繼承能夠解決什么?

上面兩種繼承都有自己的缺點(diǎn)和優(yōu)點(diǎn),那么我們是否可以取長補(bǔ)短,把兩家結(jié)合在一起?組合繼承就是用來解決這個(gè)問題的。思路就是使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。這樣,即通過在原型上定義方法實(shí)現(xiàn)了函數(shù)復(fù)用,又能夠保證每個(gè)實(shí)例都有它自己的屬性。

function Father(name) {
    this.name = name;
    this.colors = ['red','blue','green'];
}

Father.prototype.sayName = function(){
    console.log(this.name)
}

function Son(name,age){
    Father.call(this,name);
    this.age = age;
}

//繼承的實(shí)現(xiàn)
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.prototype.sayAge = function(){
    console.log(this.age);
}
var instance1 = new Son('pan',28);
instance1.colors.push('black');
console.log(instance1.colors);// red ,blue,green,black
instance1.sayName();//pan
instance1.sayAge();//28

var instance2 = new Son('lin',26);
console.log(instance2.colors);// red ,blue,green
instance2.sayName();//lin
instance2.sayAge();//26

上面的例子我們看到取長補(bǔ)短的優(yōu)勢(shì),即可以定義自己的屬性和方法,又可以使用相同的方法。這是我們常用的繼承模式,并且instanceofisPrototypeOf也能夠用于識(shí)別基于組合繼承創(chuàng)建的對(duì)象。

原型式繼承

我們先來看一個(gè)Object.create()的前身的寫法,借助原型可以基于已有的對(duì)象創(chuàng)建新對(duì)象,同時(shí)還不必因此創(chuàng)建自定義類型。

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

在一個(gè)function 內(nèi)部創(chuàng)建一個(gè)臨時(shí)性的構(gòu)造函數(shù),然后重寫這個(gè)構(gòu)造函數(shù)的原型,然后在返回這個(gè)構(gòu)造函數(shù)的新的實(shí)例。不知道你又沒有看出什么不好的地方?jīng)]?從本質(zhì)上講,object()對(duì)傳入其中的對(duì)象執(zhí)行一次淺復(fù)制。

var person = {
 name: "Nicholas",
 friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends); //"Shelby,Court,Van,Rob,Barbie" 

我們用新的方法Object.create()來重新規(guī)范上門的例子。這個(gè)方法接收兩個(gè)參數(shù):一個(gè)作用新對(duì)象原型的對(duì)象和一個(gè)為新對(duì)象定義額外屬性的對(duì)象。

var person = {
 name: "Nicholas",
 friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends); //"Shelby,Court,Van,Rob,Barbie" 

Object.create()方法的第二個(gè)參數(shù)與Object.defineProperties()方法的第二個(gè)參數(shù)格式相同:每個(gè)屬性都是通過自己的描述符定義的。以這種方式指定的任何屬性都會(huì)覆蓋原型對(duì)象上的同名屬性。例如:

var person = {
 name: "Nicholas",
 friends: ["Shelby", "Court", "Van"]
}; 
var anotherPerson = Object.create(person, {
 name: {
 value: "Greg"
 }
});

console.log(anotherPerson.name); //"Greg" 

如果只是簡單的繼承,那么原型模式就能勝任,但是想要?jiǎng)?chuàng)建構(gòu)造函數(shù),那么引用類型值的會(huì)共享這個(gè)坑是不能避免的。

寄生式繼承又能解決什么問題?

都是寄生,自然和構(gòu)造函數(shù)的寄生類似,創(chuàng)建一個(gè)僅用于封裝繼承過程的函數(shù),該函數(shù)在內(nèi)部以某種方式來增前對(duì)象,然后再返回這個(gè)對(duì)象。

function createAnother(original){
    var clone = object(original);
    clone.sayHi = function(){
        console.log('hi')
    }
    return clone;
}

接下里我們運(yùn)用上面這個(gè)函數(shù)

var person = {
 name: "Nicholas",
 friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi" 

新對(duì)象anotherPerson不僅具有person的所有屬性和方法,而且還有自己的sayHi()方法。但是此寄生式繼承不能復(fù)用函數(shù),所以效率不是很高。

終極boss 寄生組合式繼承

我們前面說的組合繼承是常用的模式,但是也有一個(gè)缺點(diǎn):那就是會(huì)調(diào)用兩次超類型構(gòu)造函數(shù)。什么意思?我們來看代碼;

function Father(name) {
    this.name = name;
    this.colors = ['red','blue','green'];
}

Father.prototype.sayName = function(){
    console.log(this.name)
}

function Son(name,age){
    Father.call(this,name);//第二次調(diào)用Father()
    this.age = age;
}

//繼承的實(shí)現(xiàn)
Son.prototype = new Father();//第一次調(diào)用Father()
Son.prototype.constructor = Son;
Son.prototype.sayAge = function(){
    console.log(this.age);
}
var instance1 = new Son('pan',28);
instance1.colors.push('black');
console.log(instance1.colors);// red ,blue,green,black
instance1.sayName();//pan
instance1.sayAge();//28

上面代碼中兩個(gè)注釋很好的反應(yīng)了這兩次構(gòu)造函數(shù)。那么寄生組合式繼承就能夠很好的優(yōu)化這個(gè)問題。通過Object.create()來很好的實(shí)現(xiàn),只需要修改一處即可。

將Son.prototype = new Father();
替換成
Son.prototype = Object.create(Father.prototype)

高效率的體現(xiàn)就在只調(diào)用了一次Father構(gòu)造函數(shù),可以避免在Son.prototype上面創(chuàng)建不必要的、多余的屬性。與此同時(shí),原型鏈還能保持不變。并且還能正常使用instanceof和isPrototypeOf()。

多繼承又如何實(shí)現(xiàn)?

上面的寄生組合式繼承只是一個(gè)單繼承,那多繼承又該如何實(shí)現(xiàn)?

我們可以用混入的方式來實(shí)現(xiàn)多個(gè)對(duì)象的繼承

//第一個(gè)構(gòu)造函數(shù)
function Father(name) {
    this.name = name;
    this.colors = ['red','blue','green'];
}

Father.prototype.sayName = function(){
    console.log(this.name)
}
//第二個(gè)構(gòu)造函數(shù)
function FatherBrother(hobby){
    this.hobby = hobby
}

function Son(name,age,hobby){
    Father.call(this,name);
    FatherBrother.call(this,hobby)
    this.age = age;
}

//繼承的實(shí)現(xiàn)
Son.prototype = Object.create(Father.prototype);
//混合
Object.assign(Son.prototype,FatherBrother.prototype)
//重新指定constructor
Son.prototype.constructor = Son;
Son.prototype.sayAge = function(){
    console.log(this.age);
}
var instance1 = new Son('pan',28,'play');
instance1.colors.push('black');
console.log(instance1.colors);// red ,blue,green,black
instance1.sayName();//pan
instance1.sayAge();//28
instance1.hobby;//play

這里關(guān)鍵點(diǎn)是:Object.assign 會(huì)把 FatherBrother原型上的函數(shù)拷貝到 Son原型上,使 Son 的所有實(shí)例都可用 FatherBrother 的方法。

整個(gè)創(chuàng)建對(duì)象的演變過程

工廠模式(簡單的添加屬性和方法) -->構(gòu)造函數(shù)模式(優(yōu)點(diǎn):可以創(chuàng)建內(nèi)置對(duì)象實(shí)例。缺點(diǎn):成員無法復(fù)用。)-->原型模式(結(jié)合構(gòu)造函數(shù)模式和原型模式兩方的優(yōu)點(diǎn),使用構(gòu)造函數(shù)定義實(shí)例屬性,而使用原型定義共享的屬性和方法。)-->原型式繼承(優(yōu)點(diǎn):不必預(yù)先定義。缺點(diǎn):會(huì)存在重寫原型)-->寄生式繼承(優(yōu)點(diǎn):效率高,不必多次調(diào)用超類型構(gòu)造函數(shù)。缺點(diǎn):復(fù)用率不高)-->寄生組合式繼承(集寄生式繼承和組合繼承的優(yōu)點(diǎn)與一身。)

如果大神您想繼續(xù)探討或者學(xué)習(xí)更多知識(shí),歡迎加入QQ一起探討:854280588
QQ

參考文章

  • 紅皮書第三版
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容