《面向对象》学习总结

155 阅读3分钟

什么是面向对象?


1.面向对象的概念

面向对象是一种以抽象方式创建基于现实世界模型的思想!英文简称OOP

2.面向对象的特征/特点

面向对象具有三大特征: 封装、继承、多态

3.使用面向对象的优点/优势

优点/优势

  • 灵活性
  • 可维护性
  • 复用性

创建面向对象有几种模式?


  • 工厂模式(创建多个相似对象)
  • 构造函数模式(不完美,实例的每个方法都是又创建了一次
  • 原型模式(有不能修改数据的问题,修改一个实力影响多个实例
  • 构造+原型(几近完美,构造函数内写属性,原型内写方法。解决了他们各自的缺点

继承


  • 原型链继承
  • 构造函数继承
  • 寄生组合继承

原型链继承

function Father(){
    this.money=1000,
    this.house=2
}
Father.prototype.eat=function(){
    console.log('noodle')
}
function Son(){
    this.name='张三'
}
var p = new Father();
Son.prototype=p;
var son=new Son();
console.log(son.name)
console.log(son.money)
console.log(son.house)
console.log(son.eat())

原型链存在的问题:

  • (1)子类型的所有实例都可以共享父类型的属性
  • (2)子类型的实例无法在不影响所有对象的情况下,给父类型的构造函数传递参数,就是你想修改某个实例属性的时候,修改的会是每个实例的属性

如此完成了原型链继承!

构造函数+原型链+call/apply继承


function Father(){
    this.money=1000,
    this.house=2,
    this.food=['banana']
}
Father.prototype.eat=function(){
    console.log('noodle')
}
function Son(){
    Father.call(this)
    this.name='张三'
}
var p = new Father();
Son.prototype=p;
Son.prototype.constructor=Son;
var son=new Son();
var son2=new Son();
son2.food.push('apple')
console.log(son.food)
console.log(son2.food)

完美解决了不能更改引用数据缺点!下面是解决传参的问题

function Father(money,house,food){
    this.money=money,
    this.house=house,
    this.food=food
}
Father.prototype.eat=function(){
    console.log('noodle')
}
function Son(name,money,house,food){
    Father.call(this,money,house,food);
    this.name=name
}
var p = new Father();//不需要在这里传参
Son.prototype=p;
Son.prototype.constructor=Son;
var son=new Son('Tom',2104132,'2套',['banana']);
var son2=new Son('Jack',210412,'1套',[]);
son2.food.push('apple')
console.log(son.food)
console.log(son2.food)

还存在的一个问题

  • 因为call本来就拷贝了一份需要继承的数据,而在p的实例中也有一份,又因为p中有继承的方法不可舍去,所以相当于写了重复的代码
  • 接下来会使用寄生式组合继承解决这个问题

寄生式组合继承


function Father(money,house,food){
    this.money=money,
    this.house=house,
    this.food=food
}
Father.prototype.eat=function(){
    console.log('noodle')
}
function Son(name,money,house,food){
    Father.call(this,money,house,food);
    this.name=name
}
function Temp(){
}
Temp.prototype=Father.prototype;
var temp = new Temp() ;//不需要在这里传参
Son.prototype=temp;
temp.constructor=Son;
var son=new Son('Tom',2104132,'2套',['banana']);
var son2=new Son('Jack',210412,'1套',[]);
son2.food.push('apple')
console.log(son.food)
console.log(son2.food)
console.log(son2.eat())

完美的解决代码重复的问题,原理就是在Son与Father增加一个叫Temp的构造函数,让Temp的实例成为Son实例与Father.prototype的纽扣。

理解:没有new Father 的动作,只是让son,son2经过temp找到了Temp.prototype的eat方法