连锁概念与用法分析,继承的含义和操作

by admin on 2019年4月4日

类继承:

后续的含义和操作

Class基本语法

正文实例讲述了ES六新特征之类(Class)和持续(Extends)相关概念与用法。分享给大家供我们参考,具体如下:

延续的想法在于,充份利用已有类的功效,在其基础上来扩展来定义新的类。

今日读书了面向对象的接续意义和有个别操作,继承,分为父类和子类,父类的局地公共数据都得以让子类实行应用,而私有化的数额,子类将不能够运用。Class
Person()与class Man(Person)那样正是Class Man(Person)是Class
Person的子类,父类Class
Person中的公共数据,都足以让子类举行利用,等于是将父类的数量赋值给子类,通过内部存款和储蓄器地址实行连接,继承还有多连续,3个父类能够被两个子类继承,下落了代码的重复使用,使代码尤其的洗练。

概述

JavaScript语言的历史观情势是由此构造函数,定义并生成新对象。下边是二个例证。

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

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

地点那种写法跟古板的面向对象语言(比如C++和Java)差别不小,很不难让新学习那门语言的程序员感到纳闷。

ES六提供了更接近守旧语言的写法,引入了Class(类)那些定义,作为目的的沙盘。通过class关键字,能够定义类。基本上,ES陆的class能够视作只是多少个语法糖,它的多方面意义,ES伍都得以成功,新的class写法只是让对象原型的写法特别清楚、更像面向对象编制程序的语法而已。上边的代码用ES⑥的“类”改写,便是下面那样。

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

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

地点代码定义了2个“类”,能够见见里边有1个constructor方法,那正是构造方法,而this重在字则表示实例对象。也正是说,ES5的构造函数Point,对应ES6的Point类的构造方法。

Point类除了构造方法,还定义了一个toString连锁概念与用法分析,继承的含义和操作。艺术。注意,定义“类”的格局的时候,前边不供给添加function以此主要字,直接把函数定义放进去了就足以了。其它,方法之间不必要逗号分隔,加了会报错。

构造函数的prototype属性,在ES陆的“类”上边继续存在。事实上,类的装有办法都定义在类的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)

 

接轨是面向对象的2个百般关键的特点,通过1个种类对另三个类别的继续,能够使代码重复利用,同时也抓好了代码的成效上的扩充,继承的语法使用Class,在Python中,一切皆对象,都能够间接只怕直接的去继续(object)对象

constructor方法

constructor办法是类的默许方法,通过new指令生成对象实例时,自动调用该措施。1个类必须有constructor方法,要是未有显式定义,三个空的constructor艺术会被默许添加。

constructor方法暗许重临实例对象(即this),完全可以钦命重临其它一个目的。

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

new Foo() instanceof Foo
// false

上面代码中,constructor函数再次回到3个崭新的指标,结果造成实例对象不是Foo类的实例。

一.主导语法

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

父类,就是被接续的类,称为父类,基类,超类。子类是后续了父类的类,称为子类,也许派生类。子类从父类继承公共的性质和公共艺术,无法三番五次私有化的多少,子类能够再而三父类,父类还可以再三再四一而再父类。2个子类能够同时继续多少个父类,同理能够使用四个父类的国有性质和集体措施,假设父类中冒出相同的性质和情势的话,使用_mro_来查看优先继承权,继承中父类尽量不要用重新的性质和艺术。

类的实例对象

生成类的实例对象的写法,与ES伍完全相同,也是运用new一声令下。借使忘记加上new,像函数那样调用Class,将会报错。

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

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

与ES51致,实例的质量除非显式定义在其本身(即定义在this目的上),不然都以概念在原型上(即定义在class上)。

与ES5一样,类的具备实例共享3个原型对象。

那也象征,能够通超过实际例的__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的原型上添加了3个printName方法,由于p1的原型便是p2的原型,因此p2也能够调用这些方式。而且,此后新建的实例p3也能够调用那几个办法。这表示,使用实例的__proto__属性改写原型,必须1对一谨慎,不引进使用,因为这会改变Class的固有定义,影响到具备实例。

JavaScript语言的守旧艺术是透过构造函数,定义并生成新对象。下边是三个例子

被接续的类称为父类,继承的类称为子类,1个父类,可以有四个子类;

子类是接二连三父类的,不过子类也足以再一次定义父类的留存的不2诀要,那称之为重写,重写体现了子类的独立性还有可变性,也叫做(多态),方法重写有四个规格一:继承的关系。二:父类存在的主意。3:子类重新定义

name属性

鉴于精神上,ES陆的Class只是ES5的构造函数的壹层包装,所以函数的过多特征都被Class继承,蕴涵name属性。

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

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

function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

子类,1旦三番五次父类,就有所了父类的特性与艺术,依照要求能够拓展增加和删除改。

本人对后续的精晓便是,父类中的方法和属性有为数不少,然则子类只关注需求的法门和总体性,父类中存放的貌似都是局地集体的内容,进步代码的复用性,子类能够每一天继承父类中的公共艺术和内容。

连锁概念与用法分析,继承的含义和操作。Class表达式

与函数一样,Class也足以选取表达式的样式定义。

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

下边代码应用表明式定义了2个类。要求专注的是,那么些类的名字是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的实例。

ES陆提供了更类似守旧语言的写法,引入了Class(类)那一个概念,作为靶子的模版。通过class关键字,能够定义类。基本上,ES陆的class可以作为只是1个语法糖,它的多边功效,ES伍都足以达成,新的class写法只是让对象原型的写法尤其清楚、更像面向对象编制程序的语法而已。上边的代码用ES陆的“类”改写,就是底下那样。

这种做法的显要利益之壹就是代码重用。

此起彼伏有几点注意:

不存在变量提高

Class不设有变量升高(hoist),那或多或少与ES五全然不相同。

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

上面代码中,Foo类应用在前,定义在后,那样会报错,因为ES6不会把变量注明提高到代码底部。那种规定的原委与下文要涉及的接续有关,必须保险子类在父类之后定义。

//定义类
class Point {
  constructor(x, y) {  //constructor 构造方法
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
var p = new Point(1, 2);

 

一.私局地属性,不可能透过对象直接待上访问,但是足以因此艺术来做客。

Class的继承

构造函数的prototype属性,在ES陆的“类”上边继续存在。事实上,类的具有办法都照旧定义在类的prototype属性上边。

示范代码一:

二.私局地艺术,不能够通过对象直接待上访问。

骨干用法

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,可是它的构造函数未有调用superbf88必发唯一官网,主意,导致新建实例时报错

2.constructor方法

#*_*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()

三.私片段属性,方法不会被子类继承,也无法被访问。

类的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);

constructor方法是类的默许方法,通过new命令生成对象实例时,自动调用该办法。1个类必须有constructor方法,假诺未有显式定义,贰个空的constructor方法会被默许添加。

输出

四.貌似境况下,私有的性质,方法都以不对外揭露的,往往用来做内部的政工,起到安全的左右和坚守

Object.getPrototypeOf()

Object.getPrototypeOf措施能够用来从子类上获取父类。

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

因此,能够动用这一个艺术判断,七个类是不是再而三了另三个类。

二、继承(Extends)

C:\Python27\python.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即能够引用父类实例的属性和方式,也足以引用父类的静态方法。

 

Class之间能够通过extends关键字贯彻持续,那比ES伍的经过改动原型链落成接二连三,要清楚和有益广大。

 

原生构造函数的继承

原生构造函数是指语言内置的构造函数,经常用来生成数据结构。ECMAScript的原生构造函数差不离有上面这几个。

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

以前,那个原生构造函数是心有余而力不足继续的,ES六允许继续原生构造函数定义子类,因为ES六是先新建父类的实例对象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

上边代码定义了2个MyArray类,继承了Array构造函数,因而就足以从MyArray生成数组的实例。这意味着,ES陆能够自定义原生数据结构(比如Array、String等)的子类,那是ES伍不可能实现的。

上面这几个事例也验证,extends重大字不仅能够用来继承类,还可以用来两次三番原生的构造函数。因而得以在原生数据结构的基础上,定义本身的数据结构。

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

当子类与父类下方法1致时,子类会覆盖父类的点子内容;其实那就是壹种重写,也是1种多态。

Class的静态方法

类也便是实例的原型,全体在类中定义的不二秘诀,都会被实例继承。要是在2个措施前,加上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目标上调用的。

上边代码中,constructor方法和toString方法之中,都冒出了super关键字,它在那边表示父类的构造函数,用来新建父类的this对象。

new.target属性

new是从构造函数生成实例的通令。ES陆为new命令引入了三个new.target质量,(在构造函数中)重临new指令成效于的那么些构造函数。假如构造函数不是通过new命令调用的,new.target会返回undefined,因而那么些天性能够用来规定构造函数是怎么调用的。

 

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

3、原生构造函数继承

原生构造函数是指语言内置的构造函数,常常用来生成数据结构。ECMAScript的原生构造函数差不多有上边那个。在此之前,这个原生构造函数是无能为力继续的。

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

ES陆同意继承原生构造函数定义子类,因为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等)的子类,那是ES伍不可能形成的。

四、Class的Generator方法

设若某些方法在此之前增加星号(*),就象征该办法是3个Generator函数。

class Foo {
  constructor(...args) {
    this.args = args;
  }
  * [Symbol.iterator]() {
    for (let arg of this.args) {
      yield arg;
    }
  }
}
for (let x of new Foo('hello', 'world')) {
  console.log(x);
}
// hello
// world

下边代码中,Foo类的Symbol.iterator方法前有一个星号,表示该措施是多个Generator函数。Symbol.iterator方法再次来到三个Foo类的默许遍历器,for…of循环会自动调用这一个遍历器。

伍、Class的静态方法

类也正是实例的原型,全数在类中定义的法子,都会被实例继承。借使在二个措施前,加上static关键字,就表示该方法不会被实例继承,而是一贯通过类来调用,那就称为“静态方法”。

class Foo {
  static classMethod() {
    return 'hello';
  }
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod 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可以调用那几个措施。

越来越多关于JavaScript相关内容感兴趣的读者可查阅本站专题:《ECMAScript6(ES六)入门教程》、《JavaScript数组操作技巧计算》、《JavaScript字符与字符串操作技巧总括》、《JavaScript数据结构与算法技巧总括》、《JavaScript错误与调节技巧总计》及《JavaScript数学生运动算用法计算》

可望本文所述对大家JavaScript程序设计有所协助。

你也许感兴趣的篇章:

  • ES陆javascript中class类的get与set用法实例分析
  • ES陆中Class类的静态方法实例小结
  • ES6中class类用法实例浅析
  • 老调重弹ES⑥中的类
  • ES陆新特点之Symbol类型用法分析
  • JavaScript中 ES陆generator数据类型详解
  • 长远浅析ES6 Class 中的 super
    关键字
  • ES六入门教程之Class和Module详解
  • JavaScript
    ES陆中CLASS的运用详解
  • JavaScript
    ES6的新特色应用新章程定义Class
  • ES陆javascript中Class类继承用法实例详解

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图