面向对象的三个特点:封装继承多态

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象的三个特点:封装继承多态相关的知识,希望对你有一定的参考价值。

封装

1、封装的概念

 

所谓封装,就是指隐藏内部的细节,不暴露在外面。

 

把构造函数里的this改成  _price;

 

 

在js里面,实现封装的方法非常简单,只需要在声明属性的时候,添加关键字即可。 一般来讲,对于私有属性,有一个不成文的规定,习惯使用_来命名属性。

 

封装后的属性(私有属性)对于外部来讲,虽然不可见,但是对于内部来讲,是可见的。

 

总结:封装后方法可以访问,但是属性信息都为undefined

 

 

2、get和set 以及属性特性

 

很多时候,我们对对象的属性进行封装,并不是为了外部访问不到,而是为了当外部访问对象属性或者设置的时候进行一定的限制。也就是说,外部能够正常的访问到进行限制了的属性。

 

Object.defineProperty(),通过这个方法可以给对象添加属性。

 

语法:Object.defineProperty(obj,prop,descriptor)

 

obj:目标对象

prop:需要添加到属性

descriptor:属性相关特性

 

descriptor参数是一个JSON对象,可以设置特性如下:

 

value:属性的值. //或者return。和  writable 一起用   默认false

writable:属性是否可写

get:一旦目标属性被访问的时候,就调用该方法

set:一旦目标属性被设置的时候,就调用该方法

enumerable:查看属性是否可以枚举,就是is hi 用for..in的时候,是否可以遍历出来。  True  false

 

 

 

如果要设置多个属性,可以调用object.object.defineProperties(),这样就可以设置多个属性。使用该方法接收的参数也是有一定变化的

 

语法:object.defineProperties(obj,{JSON})

 

JSON对象 {prop:{descriptor},prop:{descriptor},…. } 

for(let I in stu) 

{

console.log(i);

}

 

继承

 

 

1、继承基本介绍

 

在程序语言里面,面向对象种所指的继承就是一个子类去继承一个父类。子类在继承了父类之后,父类所拥有的属性和方法自动就都拥有了。

 

继承的好处:

继承最大的好处,就在于代码能够进行复用。例如有两个类,就给他们写个父类。

 

继承缺点:

首先如果我们继承设计得非常复杂,那么整个程序设计也会变得庞大和复杂。

 

如果是像C++那样的多继承语言,那么可能还会出现菱形继承的问题。 //只有c++是多继承。改动之后 最下层方法不知道用哪一个

 

 

单继承:只有一个父类

多继承:有多个类

 

 

菱形继承问题:首先需要说明,菱形继承问题只会在多继承里面才会出现。

 

例如:a和b是继承base类,假设base类有一个成员方法,那么a和b都会有这个成员方法,这个时候a和b又分别对成员方法进行了修改。接下来让一个c来同时继承a和b,问题来了,对于同名的方法,究竟使用哪一个,这就是所谓的菱形继承问题。这个是属于设计上的问题。

 

由于js是单继承语言,所以一定程度上避免了菱形继承的问题。

 

 

2、js里面实现继承的方法

 

(1)对象冒充

所谓对象冒充,就是指用父类(构造函数)去充当子类的属性

 

temp=构造函数名字

 

但是,使用对象冒充实现的继承有一个缺点,缺陷就是无法继承到原型对象上面的属性或者方法

 

 

从对象冒充又衍生出来了一种通过call或者apply来实现继承,本质上还是对象冒充。

他俩基本上一样,只是参数接收不同

 

function.call(abj,arg1,arg2,arg3…)

 

Function.apply(obj,[arg1,arg2,arg3,arg4…])

 

 

Obj:代表当前对象

arg:代表一个参数列表

 

总结:简单来讲,就是将a所拥有的东西应用到b的环境里面,让b也拥有和a相同的东西,但是作用域还是b的,而不是a的。

 

c1.show.call(c2);

 

 

(2)通过原型对象来实现继承

 

这种方法的核心思路就是改变构造函数的prototype的属性值,但是这种方式也有一个缺点,就是无法传参

 

 

(3) 混合方式实现继承

为了实现能够同时传参以及能够继承到原型对象上面的属性和方法,采用上面两种方式的结合。

 

   Person.call(this, name, age); //call 方法

 

 

Student.prototype = new Person();

 

 

(4)es6 实现继承的方式

 

埃ES6里面添加了关键字extends  

 

class  子  extends   父  {

  Constructor(name,age,gender,score){

super(name,age)

This..

 

}

 

}

super//访问父类

 

class Student extends Person { //extends关键字

    constructor(name,age,gender,score){

        super(name,age);//访问父类的内容

        this.gender=gender;

        this.score=score;

 

 

多态 

 

1、什么事多态

 

所谓多态,就是指不同的对象的同名方法却有不同的效果,这就是多态。

 

最常见的多态即使to string();

虽然每个对象都有tostring()方法,但是并不是每一个对象的表现形式都一样的

 

转数组有逗号分隔

转数字 没有

 

2、实现多态

 

在继承父类当法的时候直接进行覆盖即可,这样就实现了多态。

 

 

(1)混合方式实现多态

 

给子类原型对象添加同名的方法;

 

调用同名方法。表现形式不一样。

 

 

(2)es6中实现多态

 

类里 方法也可以看作是一个属性

 

在子类里添加一个同名的属性进行调用

 

 

重写或重载。

我们重写

 

 

扩展

 

1、从对象创建对象

 

实际上在js里面创建对象时可以完全避免使用构造函数(或者说类,)而时使用另外一个对象作为原型来创建对象

使用

 

boject.create();

 

这个方法还可以传入第二个参数,第二个参数是json对象,用来对对象的属性设置相关特性。

 

 

 

2、混入

 

混入就是一种不需要继承,就将某些对象的属性和方法添加到另一个对象上面。通过Object.assing()来实现

 

语法:

Object.assign(target,a,b,c,d,…..)

 

 

Let a={ } ;

Let  b={

name:”xiejie”,

age:18

}

let c={

gender:male;

score:100;

}

 

Object.assign(a,b,c);

 

Console .log(a.name);

 

 

 

如果混入对象中包含同名的属性,那么后面会覆盖前面的。

记住:混入优于继承

 

 

 

3、改写this的指向

 

this默认的指向:如果是全局环境或者函数里面调用,包括嵌套,这个this指向全局对象

Node  global 

浏览器  window

 

如果通过对象的方式来调用,那么this指向当前对象。

 

但是,这个this的指向,我们是可以改变的

 

(1)通过call或者apply可以改变this的指向

 

 

(2)通过bind()方法强行绑定this指向

 

 

(3)箭头函数的this

 

箭头函数基本语法

 

(形参)=>{函数体}

 

如果只有一个参数

形参=>{函数体}

  

这里与其数是箭头函数改变了this指向,更贴切的来讲,汗透函数的this指向和其他函数不一样,箭头函数的this指向始终是外部的作用域

 

以上是关于面向对象的三个特点:封装继承多态的主要内容,如果未能解决你的问题,请参考以下文章

C++作为面向对象语言的三个基本特征:封装,继承和————

java面向对象的三大特征?

面向对象的多态详解 !!

面向对象是什么?

Java面向对象三大特征之继承和多态

PHP面向对象三大特点学习(充分理解抽象封装继承多态)