返回

面向对象,面向你(二)

前端

面向对象,面向你(二)

在上一节中,我们了解了面向对象语言的基本概念 ,以及它与过程化语言的不同之处。在这一节中,我们将深入探讨面向对象语言的一个重要特性——继承

继承 是面向对象语言中一个最为人津津乐道的概念。许多面向对象语言都支持两种继承方式:接口继承实现继承 。接口继承只继承方法签名,而实现继承则继承实际的方法。因为在 JavaScript 中,函数没有签名(签名可以用来实现类型检查、函数重载、接口等等,而这些东西 js 都不支持),所以 js 中只有实现继承

实现继承

实现继承,顾名思义,就是继承父类的实现。在 js 中,实现继承可以使用 extends 。例如:

class Parent {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }

  sayHello() {
    super.sayHello();
    console.log(`I am ${this.age} years old`);
  }
}

const child = new Child('小明', 18);
child.sayHello();

这段代码中,Parent 类是一个父类,Child 类是一个子类。子类 Child 继承了父类 Parent 的所有属性和方法,并且还增加了自己的属性和方法。

当我们创建一个 Child 类对象时,首先会执行 Parent 类的构造函数,然后执行 Child 类的构造函数。这样,Child 类对象就继承了父类 Parent 的所有属性和方法。

子类可以覆盖父类的方法。例如,在上面的代码中,Child 类重写了 sayHello() 方法。当调用 Child 类对象 childsayHello() 方法时,会执行 Child 类中的 sayHello() 方法,而不是 Parent 类中的 sayHello() 方法。

接口继承

接口继承与实现继承不同,它只继承方法签名,而不继承实际的方法。在 js 中,接口继承可以使用 implements 关键字。例如:

interface IAnimal {
  eat(): void;
  sleep(): void;
}

class Cat implements IAnimal {
  eat() {
    console.log('喵喵喵,我吃猫粮');
  }

  sleep() {
    console.log('呼噜呼噜,我在睡觉');
  }
}

class Dog implements IAnimal {
  eat() {
    console.log('汪汪汪,我吃骨头');
  }

  sleep() {
    console.log('呼噜呼噜,我在睡觉');
  }
}

const cat = new Cat();
cat.eat();
cat.sleep();

const dog = new Dog();
dog.eat();
dog.sleep();

这段代码中,IAnimal 接口定义了两个方法:eat()sleep(). Cat 类和 Dog 类都实现了 IAnimal 接口,因此它们都必须实现这两个方法。

当我们创建一个 Cat 类对象或 Dog 类对象时,会自动继承 IAnimal 接口的所有方法。但是,这些方法的具体实现是由 Cat 类和 Dog 类自己决定的。

接口继承可以使代码更加模块化和可重用。例如,如果我们有一个程序需要处理各种动物,我们可以定义一个 IAnimal 接口,然后让不同的动物类实现这个接口。这样,我们就只需要编写一次 IAnimal 接口,就可以处理各种动物了。

总结

继承是面向对象语言中一个非常重要的特性。它可以使代码更加模块化、可重用和易于维护。在 js 中,实现继承可以使用 extends 关键字,接口继承可以使用 implements 关键字。