ES6中类与继承的理解(java对比记忆)

前言

先上两段代码: java中定义类:javascript

public class Person{
    private String name;
    private int age;
   
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void getInfo(){ 
        System.out.println(name+age);
    }
}
复制代码

Es6中定义一个类:html

class Person{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    getInfo(){
        return this.name+','+this.age;
    }
}
//调用
let person=new Person("koala","123");
复制代码

经过上面两段代码引出咱们今天要说的相关内容java

类中的变量

  • 两者异 在java中能够直接声明各类类型的私有变量,在ES6中的类不能够直接在类中声明私有变量,声明后会报错。 注意:可是随着v8的更新,在node12版本中,ES增长了一些新规范,其中就有支持类的私有变量这一条。 代码以下:
class Greet {
  #name = 'World';
  get name() {
    return this.#name;
  }
  set name(name) {
    this.#name = name;
  }
  sayHello() {
    console.log(`Hello, ${this.#name}`);
  }
}
复制代码

在类的外部或去#name变量会抛出异常node

const greet = new Greet()
greet.#name = 'NewName';
// -> SyntaxError
console.log(greet.#name)
// -> SyntaxError
复制代码

类中的构造函数

  • 两者同:

若是声明一个一个类的时候没有声明构造函数,那么会默认添加一个空的构造函数,构造函数在new实例化一个对象的时候会被调用程序员

  • 两者异:

在ES6中,能够在构造函数中直接定义类方法(类方法也能够是箭头函数),代码以下面试

constructor(name,age){
          this.name=name;
          this.age=age;
          this.getInfo()=()=>{
              console.log("name"+this.name+"sex"+this.sex);
             }         
 } 
复制代码

类中的方法

  • 两者同:

有参,无参函数,函数调用方式相同。静态方法,ES6中用static声明一个静态方法,方法只能用类名直接调用,不能经过类的实例调用微信

  • 两者异:

ES6在类中声明函数,无需使用function关键字,java的类中必须使用关键字声明函数。koa

ES6方法内部访问类属性的时候须要this来访问,java不须要。函数

ES6的构造函数中能够定义函数,java不可。学习

类中的继承

  • 两者同:

继承关键字都是extends,super方法的使用

  • 两者异:

继承的调用:

ES6须要注意的是super只能调用父类方法,而不能调用父类的属性,方法定义再原型链中,属性定义在类的内部

java中,super关键字,能够经过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

继承过程当中的构造函数:

ES6中,子类中,super方法是必须调用的,由于子类自己没有自身的this对象,须要经过super方法拿到父类的this对象。在子类中,没有构造函数,那么在默认的构造方法内部自动调用super方法,继承父类的所有属性,子类的构造方法中,必须先调用super方法,而后才能调用this关键字声明其它属性。(子类的this就是在这里调用super以后,拿到父类的this,而后修改这个this来的)

class Student extends Person{
    constructor(name,sex){
        console.log(this);//Error
        super(name,sex);
        this.sex=sex;
    }
}
复制代码

java中,子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。若是父类的构造器带有参数,则必须在子类的构造器中显式地经过 super 关键字调用父类的构造器并配以适当的参数列表。

若是父类构造器没有参数,则在子类的构造器中不须要使用 super **关键字调用父类构造器,系统会自动调用父类的无参构造器。 **

看一段面试问的比较多的代码实例:

class SuperClass {
  private int n;
  SuperClass(){
    System.out.println("SuperClass()");
  }
  SuperClass(int n) {
    System.out.println("SuperClass(int n)");
    this.n = n;
  }
}
class SubClass extends SuperClass{
  private int n;
  
  SubClass(){
    super(300);
    System.out.println("SubClass");
  }  
  
  public SubClass(int n){
    System.out.println("SubClass(int n):"+n);
    this.n = n;
  }
}
public class TestSuperSub{
  public static void main (String args[]){
    SubClass sc = new SubClass();
    SubClass sc2 = new SubClass(200); 
  }
}
复制代码

输出结果:

SuperClass(int n)
SubClass SuperClass() SubClass(int n):200 复制代码

ES6中的类与原型链的关系

看一下文初定义的一个的javascript类。它和原型链对等的代码以下:

//类
class Person{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    getInfo(){
        return this.name+','+this.age;
    }
}

//原型链
function Person(name, age) {
    this.name = name;
    this.age = age;
}
  
Person.prototype.getInfo = function () {
    return this.name+','+this.age;
};
console.log(Person)
let person = new Person("koala", 123);
复制代码

针对代码进行一下说明讲解:

  • 声明的新对象都不具有原型链(类)的函数,可是却能够调用原型链的函数
Object.getOwnPropertyNames(p)//[ 'name', 'age' ] 从输出结果能够看出只有这两个属性,不具备getInfo函数
console.log(p.getInfo());//输出结果 kaola,123
复制代码

无论是在原型链仍是类中,获取的结果都是['name','age']

  • 直接打印class,发现类实际是个函数,就是对应的构造函数,this关键字表明实例对象,简单的说是class就是构造函数,prototype对象的constructor属性,直接指向“类”的自己。
//直接打印类
console.log(Person);
console.log(Point===Point.prototype.constructor);//true
复制代码
  • 与ES5同样,实例的属性除非显式定义在其自己(即定义在this对象上),不然都是定义在原型上(即定义在class上)。
person.hasOwnProperty('name') // true
 person.hasOwnProperty('age') // true
 person.hasOwnProperty('getInfo') // false
 person.__proto__.hasOwnProperty('getInfo') // true getInfo是原型对象的属性
复制代码
  • 类的全部实例共享一个原型对象
let person1 = new Person("koala1", 124);
console.log(person.__proto__===person1.__proto__);//true
复制代码
  • 类的实例 构造方法默认返回实例对象(this) 可是返回this能够修改

ES6中类的出现有什么好处

  • js中的类仍然是基于原型的。即便在建立类后修改类的构造函数上的原型对象仍然不会有任何问题。 例子代码以下:
class Foo {
    constructor(name) {
        this.name = name;
    }

    test1() {
        console.log("test1: name = " + this.name);
    }
}
Foo.prototype.test2 = function() {
    console.log("test2: name = " + this.name);
};
复制代码
  • 类的语法简单,不易出错,尤为是在继承层次结构上简单不少。

  • 类保护你免受没法使用构造函数使用新的常见错误(经过让构造函数抛出异常,若是这不是构造函数的有效对象)。

代码例子以下: ES6中类出现后实现继承:

// ES6
class Person {
    constructor(first, last) {
        this.first = first;
        this.last = last;
    }

    personMethod() {
        // ...
    }
}

class Employee extends Person {
    constructor(first, last, position) {
        super(first, last);
        this.position = position;
    }

    employeeMethod() {
        // ...
    }
}

class Manager extends Employee {
    constructor(first, last, position, department) {
        super(first, last, position);
        this.department = department;
    }

    managerMethod() {
        // ...
    }
}
复制代码

ES6中类未出现前实现继承:

// ES5
var Person = function(first, last) {
    if (!(this instanceof Person)) {
        throw new Error("Person is a constructor function, use new with it");
    }
    this.first = first;
    this.last = last;
};

Person.prototype.personMethod = function() {
    // ...
};

var Employee = function(first, last, position) {
    if (!(this instanceof Employee)) {
        throw new Error("Employee is a constructor function, use new with it");
    }
    Person.call(this, first, last);
    this.position = position;
};
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.employeeMethod = function() {
    // ...
};

var Manager = function(first, last, position, department) {
    if (!(this instanceof Manager)) {
        throw new Error("Manager is a constructor function, use new with it");
    }
    Employee.call(this, first, last, position);
    this.department = department;
};
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.managerMethod = function() {
    // ...
};

复制代码

附录:

java中的继承 www.runoob.com/java/java-i…

以为本文对你有帮助?请分享给更多人

欢迎你们关注个人公众号——程序员成长指北,公众号会一直分享有价值的技术干货文章,学习资料,面试等内容,也可加群共同窗习,共同进步。请自行微信搜索——“程序员成长指北”

个人公众号.jpg
相关文章
相关标签/搜索