类继承:

继续的含义和操作

Class基本语法

持续的主见在于,充份利用本来就有类的法力,在其底蕴上来扩展来定义新的类。

后天读书了面向对象的一而再意义和局部操作,世袭,分为父类和子类,父类的一些公共数据都足以让子类举办应用,而私有化的数据,子类将不能使用。Class
Person()与class Man(Person)那样便是Class Man(Person)是Class
Person的子类,父类Class
Person中的公共数据,都足以让子类进行应用,等于是将父类的数额赋值给子类,通过内部存款和储蓄器地址进行接二连三,世襲还应该有多三番两次,叁个父类可以被四个子类袭承,减弱了代码的重复使用,使代码更加的简洁明了。

概述

JavaScript语言的价值观艺术是透过构造函数,定义并生成新对象。上边是二个例子。

function Point(x,y){
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

上边这种写法跟古板的面向对象语言(比方C++和Java卡塔 尔(英语:State of Qatar)差距非常大,相当轻松让新学习那门语言的程序猿以为纠缠。

ES6提供了更犹如古板语言的写法,引进了Class(类卡塔 尔(英语:State of Qatar)这么些定义,作为目的的模版。通过class第一字,能够定义类。基本上,ES6的class可以当做只是一个语法糖,它的绝半数以上职能,ES5都足以成功,新的class写法只是让对象原型的写法越发清晰、更像面向对象编制程序的语法而已。下边包车型大巴代码用ES6的“类”改写,便是下边那样。

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

地点代码定义了二个“类”,可以见到里边有一个constructor措施,那便是构造方法,而this第一字则表示实例对象。也正是说,ES5的构造函数Point,对应ES6的Point类的构造方法。

Point类除了构造方法,还定义了贰个toString措施。注意,定义“类”的办法的时候,前边无需充足function这么些至关心注重要字,直接把函数定义放进去了就能够了。其余,方法之间不供给逗号分隔,加了会报错。

构造函数的prototype天性,在ES6的“类”上面继续存在。事实上,类的具备办法都定义在类的prototype属性上边

class Point {
  constructor(){
    // ...
  }

  toString(){
    // ...
  }

  toValue(){
    // ...
  }
}

// 等同于

Point.prototype = {
  toString(){},
  toValue(){}
};

在类的实例上面调用方法,其实就是调用原型上的法门。

class B {}
let b = new B();

b.constructor === B.prototype.constructor // true

类的里边有着定义的方法,都是多如牛毛的(non-enumerable卡塔尔国。

 

气吞山河是面向对象的叁个卓绝首要的特点,通过二个品种对另三个档次的持续,能够使代码重复利用,相同的时间也抓实了代码的功效上的扩展,世袭的语法使用Class,在Python中,一切皆对象,都足以间接可能直接的一了百了袭(object卡塔尔国对象

constructor方法

constructor主意是类的暗许方法,通过new指令生成对象实例时,自动调用该方法。多个类必需有constructor方法,万生机勃勃未有显式定义,二个空的constructor措施会被私下认可增添。

constructor主意暗中同意重临实例对象(即this卡塔尔,完全可以钦赐重返别的一个指标。

class Foo {
  constructor() {
    return Object.create(null);
  }
}

new Foo() instanceof Foo
// false

地点代码中,constructor函数重临七个全新的靶子,结果形成实例对象不是Foo类的实例。

Parent Class(父类)
与 Child Class(子类):

父类,便是被持续的类,称为父类,基类,超类。子类是三回九转了父类的类,称为子类,大概派生类。子类从父类世襲公共的天性和集体措施,不能够世襲私有化的多寡,子类能够持续父类,父类还足以继续三番五遍父类。叁个子类能够同时继续八个父类,同理能够利用五个父类的共用属性和公共措施,假设父类中冒出雷同的性子和章程的话,使用_mro_来查阅优先世襲权,继承中父类尽量不要用重新的属性和办法。

类的实例对象

生成类的实例对象的写法,与ES5截然等同,也是选拔new命令。若是忘记加上new,像函数那样调用Class,将会报错。

// 报错
var point = Point(2, 3);

// 正确
var point = new Point(2, 3);

与ES5等同,实例的性质除非显式定义在其自己(即定义在this对象上卡塔尔,否则都是概念在原型上(即定义在class上)。

与ES5一样,类的享有实例分享三个原型对象。

这也象征,能够经超过实际例的__proto__属性为Class增添艺术。

var p1 = new Point(2,3);
var p2 = new Point(3,2);

p1.__proto__.printName = function () { return 'Oops' };

p1.printName() // "Oops"
p2.printName() // "Oops"

var p3 = new Point(4,2);
p3.printName() // "Oops"

地点代码在p1的原型上增加了一个printName方法,由于p1的原型正是p2的原型,因此p2也得以调用那一个法子。何况,从今以后新建的实例p3也足以调用那几个方法。那意味,使用实例的__proto__天性改写原型,必需风度翩翩对意气风发严谨,不推荐使用,因为那会校订Class的本来定义,影响到独具实例。

被三翻五次的类称为父类,世袭的类称为子类,三个父类,能够有多个子类;

子类是世袭父类的,可是子类也得以重新定义父类的存在的办法,这名称叫重写,重写展示了子类的独立性还或然有可变性,也称为(多态卡塔 尔(英语:State of Qatar),方法重写有四个尺码1:继承的涉及。2:父类存在的不二秘技。3:子类重新定义

name属性

出于精气神儿上,ES6的Class只是ES5的构造函数的大器晚成层包装,所以函数的不在少数个性都被Class世襲,包罗name属性。

class Point {}
Point.name // "Point"

name属性总是回到紧跟在class根本字背后的类名。

子类,生机勃勃旦一连父类,就全体了父类的性质与办法,依照供给可以举办增加和删除改。

自身对后续的领会就是,父类中的方法和属性有为数不菲,不过子类只关怀须求的艺术和总体性,父类中贮存的相仿都以意气风发对集体的剧情,提高代码的复用性,子类能够随即世袭父类中的公共艺术和剧情。

Class表达式

与函数雷同,Class也能够行使表明式的款式定义。

const MyClass = class Me {
  getClassName() {
    return Me.name;
  }
};

地方代码应用表明式定义了八个类。须要介意的是,这几个类的名字是MyClass而不是MeMe只在Class的内部代码可用,指代当前类。

let inst = new MyClass();
inst.getClassName() // Me
Me.name // ReferenceError: Me is not defined

地点代码表示,Me只在Class内部有定义。

只要Class内部没用到的话,能够轻便Me,也等于足以写成下边包车型大巴样式。

const MyClass = class { /* ... */ };

利用Class表明式,能够写出当下实施的Class。

let person = new class {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }
}('张三');

person.sayName(); // "张三"

下面代码中,person是二个当即实行的Class的实例。

这种做法的第风流倜傥收益之风流罗曼蒂克正是代码重用。

波涛汹涌有几点注意:

海市蜃楼变量进步

Class不设有变量进步(hoist卡塔 尔(阿拉伯语:قطر‎,这点与ES5通通两样。

new Foo(); // ReferenceError
class Foo {}

地点代码中,Foo类应用在前,定义在后,那样会报错,因为ES6不会把变量申明升高到代码底部。这种规定的从头至尾的经过与下文要提到的接轨有关,必需保险子类在父类之后定义。

 

1.私有的属性,不能够通过对象直接待上访谈,可是足以经过措施来访问。

Class的继承

亲自去做代码1:

2.私局地艺术,不可能由此对象直接访谈。

主干用法

Class之间能够经过extends关键字落到实处持续,那比ES5的通过改动原型链完毕持续,要清晰和有协理广大。

class ColorPoint extends Point {}

地点代码定义了三个ColorPoint类,该类通过extends关键字,继承了Point类的装有属性和情势。不过出于未有安排任何代码,所以那八个类完全平等,等于复制了叁个Point类。下面,我们在ColorPoint在那之中加上代码。

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

上面代码中,constructor方法和toString主意之中,都冒出了super尤为重要字,它在这里地球表面示父类的构造函数,用来新建父类的this对象。

子类必得在constructor艺术中调用super方法,不然新建实例时会报错。那是因为子类没有协调的this对象,而是继续父类的this对象,然后对其进展加工。倘诺不调用super艺术,子类就得不到this对象。

class Point { /* ... */ }

class ColorPoint extends Point {
  constructor() {
  }
}

let cp = new ColorPoint(); // ReferenceError

上面代码中,ColorPoint继续了父类Point,但是它的构造函数未有调用super办法,引致新建实例时报错

#*_*coding:utf-8*_*

class perent_class(object):
    def __init__(self,name):
        self.name = name

    def printName(self):
        print('你的名字是:'+self.name)


class child_class(perent_class):
    def __init__(self,name,age):
        super(child_class,self).__init__(name) #初始化类super()函数返回类对象
        self.age = age


if __name__=="__main__":
    child_class('xzdylyh','25').printName()

3.私部分属性,方法不会被子类世袭,也无法被访问。

类的prototype属性和__proto__属性

绝大多数浏览器的ES5落实之中,每叁个对象都有__proto__个性,指向对应的构造函数的prototype属性。Class作为构造函数的语法糖,同期有prototype属性和__proto__属性,因而同时设有两条继承链。

(1)子类的__proto__本性,表示构造函数的世袭,总是指向父类。

(2)子类prototype属性的__proto__天性,表示方法的接二连三,总是指向父类的prototype属性。

class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

上面代码中,子类B__proto__性情指向父类A,子类Bprototype属性的__proto__个性指向父类Aprototype属性。

这么的结果是因为,类的继续是依据上边包车型大巴形式达成的。

class A {
}

class B {
}

// B的实例继承A的实例
Object.setPrototypeOf(B.prototype, A.prototype);

// B继承A的静态属性
Object.setPrototypeOf(B, A);

输出

4.相同情况下,私有的品质,方法都以不对外发表的,往往用来做内部的作业,起到平安的左右和职能

Object.getPrototypeOf()

Object.getPrototypeOf主意能够用来从子类上赢得父类。

Object.getPrototypeOf(ColorPoint) === Point
// true

因此,能够运用这一个措施判断,一个类是否一连了另四个类。

C:Python27python.exe D:/weixin/temp/temp.py
你的名字是:xzdylyh

Process finished with exit code 0

�������rz�+��

super关键字

super本条主要字,有三种用法,含义不相同。

(1)作为函数调用时(即super(...args)),super意味着父类的构造函数。

(2)作为对象调用时(即super.propsuper.method()),super表示父类。注意,那时候super即能够引用父类实例的习性和方法,也得以引用父类的静态方法。

 

 

原生构造函数的后续

原生构造函数是指语言内置的构造函数,常常用来生成数据结构。ECMAScript的原生构造函数差不离有下边那一个。

  • Boolean()
  • Number()
  • String()
  • Array()
  • Date()
  • Function()
  • RegExp()
  • Error()
  • Object()

以前,那个原生构造函数是敬谢不敏继续的,ES6同意世襲原生构造函数定义子类,因为ES6是先新建父类的实例对象this,然后再用子类的构造函数修饰this,使得父类的具有行为举止都得以世袭。上边是三个继续Array的例子。

class MyArray extends Array {
  constructor(...args) {
    super(...args);
  }
}

var arr = new MyArray();
arr[0] = 12;
arr.length // 1

arr.length = 0;
arr[0] // undefined

上边代码定义了七个MyArray类,继承了Array构造函数,因而就足以从MyArray生成数组的实例。那代表,ES6方可自定义原生数据结构(比方Array、String等卡塔 尔(阿拉伯语:قطر‎的子类,那是ES5不能到位的。

地点这么些例子也作证,extends重视字不只能够用来世袭类,还足以用来继续原生的构造函数。由此能够在原生数据结构的底工上,定义本人的数据结构。

当子类与父类下方法后生可畏致时,子类会覆盖父类的点子内容;其实那便是风华正茂种重写,也是意气风发种多态。

Class的静态方法

类也就是实例的原型,全体在类中定义的议程,都会被实例世袭。如果在四个方式前,加上static紧要字,就意味着该情势不会被实例继承,而是向来通过类来调用,那就叫做“静态方法”。

class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: undefined is not a function

下边代码中,Foo类的classMethod主意前有static关键字,申明该方式是一个静态方法,能够直接在Foo类上调用(Foo.classMethod()卡塔尔国,并不是在Foo类的实例上调用。借使在实例上调用静态方法,会抛出多少个八花九裂,表示一纸空文该方法。

父类的静态方法,能够被子类世襲。

class Foo {
  static classMethod() {
    return 'hello';
  }
}

class Bar extends Foo {
}

Bar.classMethod(); // 'hello'

地方代码中,父类Foo有三个静态方法,子类Bar能够调用那些措施。

静态方法也是足以从super对象上调用的。

new.target属性

new是从构造函数生成实例的一声令下。ES6为new命令引进了二个new.target属性,(在构造函数中卡塔尔国重临new一声令下作用于的可怜构造函数。若是构造函数不是因而new一声令下调用的,new.target会返回undefined,因而那一个天性可以用来规定构造函数是怎么调用的。

 

相关文章