假设我们有下面3个类,每个类都在自己单独的文件里面
/** 水果类 */
abstract class Fruit {
constructor(public color: string) {}
public juice() {
if (this instanceof Apple) {
return 'whtie juice';
} else if (this instanceof Grapes) {
return 'purple juice';
}
}
}
/** 苹果 */
class Apple extends Fruit {
public price: number;
constructor(color: string, price: number) {
super(color);
this.price = price;
}
}
/** 葡萄 */
class Grapes extends Fruit {
constructor(color: string) {
super(color);
}
}
上面的代码中规定了,所有继承自Fruit
类的水果都能用来榨汁,并且这个方法已经实现了,并且Fruit
类是抽象的,不能直接初始化,现在的问题是,加入我想要初始化一个Apple
实例,在Apple
继承自Fruit
,那么在调用Apple
的构造函数的时候,需要先调用Fruit
的构造函数,但是在Fruit
类里面,引用到了其他类,比如现在正在初始化的Apple
类,this instanceof Apple
中的Apple
需要在Fruit
类所在的文件里面引用,所以现在就成了
创建Apple
实例,先初始化Fruit
,需要引用Apple
,
一般这种情况怎么处理呢,或者怎么避免循环引用,当然如果能有更好的方式代替this instanceof Apple
来确定当前的类型那就更好了
这个 Fruit 抽象类的 juice 方法就是个错误的设计。
你在设计 Fruit 抽象类的时候你心里就应该想,我现在只管 Fruit 类的设计,以后会有 Apple 还是 Banana 类那可能是另一个程序员的事儿。好,现在你要一个榨汁方法,但需求是不同水果会榨不同的汁,怎么解决这个问题?当然是让子类自己去实现会产生什么样的果汁,你只管榨的部分。这样你就引入一个抽象方法叫产生果汁,子类实现,你调用就好。如果榨的部分实在没什么内容要写,比如就一个 return ,好吧那你就没必要在这个父类中实现榨汁,整个方法标记为 abstract 全盘让子类自己去实现就好了。
所以 Fruit 类根本没必要也不应该知道具体有几个类继承了它。