之前我的这篇文章 TYPESCRIPT 关于interface理解 介绍了interface的一些理解。
其中提到了在面向对象编程时,多态的实现interface可以做到,同理abstract也可以做到。不过使用它们,有着相同点和不同点,下面先来介绍一下abstract的使用,再来总结它们之间的异同点。
介绍abstract 相关知识
abstract,含义:抽象。
可以用来定义类和方法,让他们变成抽象类和抽象方法
抽象类:
abstract class Person {
name: string;
constructor(name) {
this.name = name;
}
abstract sayHi(); //抽象方法
}
注意事项:
- 抽象类是不允许被实例化的
let test = new Person('小明');
//报错
//Cannot create an instance of an abstract class.
- 抽象类中的抽象方法必须在子类中实现
class Child extends Person {
run() {
console.log('learn to run...');
}
}
let child = new Child();
//这样写会报错
//Non-abstract class 'Child' does not implement inherited abstract member 'sayHi' from class 'Person'.
修改成这样的,就可以正常编译通过了:
class Child extends Person {
run() {
console.log(this.name + ' ' + 'learn to run...');
}
sayHi() {
console.log('hello,everyone');
}
}
let child = new Child('小明');
child.sayHi();
child.run();
执行ts转化为js文件的操作后,打印结果如下:
hello,everyone
小明 learn to run...
那会到正题上,上一篇关于 typescript中的interface的理解,我们使用了造门的例子。那使用abstract再来实现一遍例子吧。
- 将门的形状定义为一个接口,为后面对象赋值使用
interface DoorAttribute {
height: number;
width: number;
color: string;
texture: string;
}
- 车和房子都需要建门,所以将 建门的抽象方法 此时定义在 抽象父类 中,子类继承父类后再去具体实现这个抽象方法。
如下,为抽象的父类Thing
abstract class Thing {
height;
width;
color;
texture;
setAttribute(doorAttribute: DoorAttribute) {
// console.log('==>',doorAttribute)
this.height = doorAttribute.height;
this.width = doorAttribute.width;
this.color = doorAttribute.color;
this.texture = doorAttribute.texture;
};
abstract buildDoor();
}
相比较上篇文章,类Thing 的定义多了关键字abstract,同时在里面也多了抽象方法buildDoor
-
然后,根据上述所说的abstract的特性,我们在子类中实现这个抽象方法buildDoor
在子类House, 它继承了父类Thing,在类里,具体实现buildDoor抽象方法
class House extends Thing {
buildDoor() {
console.log(`house door is, height: ${this.height},width:${this.width}
color: ${this.color}, texture: ${this.texture}!`);
}
}
在子类Car, 它同样也继承了抽象父类Thing,在类里,具体实现buildDoor抽象方法
class Car extends Thing {
buildDoor() {
console.log(`car door is, height: ${this.height},width:${this.width}
color: ${this.color}, texture: ${this.texture}!`);
}
}
这里与之前interface实现例子的区别是,删去了 implements Door 这些代码
- 实例化House和car,测试验证结果
const house = new House();
const houseValue: DoorAttribute = { height: 800, width: 200, color: 'red', texture: 'wood', };
house.setAttribute(houseValue);
house.buildDoor();
const car = new Car();
const carValue: DoorAttribute = { height: 300, width: 600, color: 'black', texture: 'aluminum', };
car.setAttribute(carValue);
car.buildDoor();
经过typescript的编译和转化,打印结果如下,与之前的interface实现是一致的
house door is, height: 800,width:200
color: red, texture: wood!
car door is, height: 300,width:600
color: black, texture: aluminum!
所以,综上所述,我这边想总结下,在typescript中,interface和abstract的异同点:
相同点:
1、都是关键字
2、都可以体现多态的特点
3、interface实现类、abstract class的子类,都必须要实现已经声明的抽象方法
不同点:
总的来说,抽象类和接口在很大程度上都是可以互相替换使用的,但就是由于抽象类本身具备单继承局限性,所以当抽象类和接口全部都可以使用的时候优先考虑接口,因为接口没有单继承局限性。
以下是写本篇文章的,借鉴的一些参考文章: