基类:
abstract class Poly extends Entity {
kind?: string;
constructor() {
super();
this.kind = this.constructor.name;
}
}
资产类可以从Poly继承:
abstract class Asset extends Poly {}
安全类不能从poly继承:
class Security extends Asset {}
有一些选择吗?
这就是我实现多态的方法:
abstract class Asset extends Poly {}
class Security extends Asset {}
class Bond extends Asset {}
const assets:Asset[] = [];
assets.push(new Security());
assets.push(new Bond());
assets.forEach(s => console.log(s.kind))
答案 0 :(得分:1)
我可以考虑在运行时上执行此操作的方法。我怀疑它可以在TypeScript编译时完成。
我的理解是您想禁用间接子类。因此Asset
可以,因为它是Poly
(Poly
<-Asset
)的直接子类,但是Security
则不可行,因为它是间接子类( Poly
<-Asset
<-Security
)。
在运行时,您可以通过检查原型链并从Poly
构造函数中抛出来完成此操作。这是一个不依赖于任何ES2015 +功能的版本(因此,如果您将TypeScript配置为输出ES5级代码,它仍然可以正常工作):
// In Poly
constructor() {
super();
if (Object.getPrototypeOf(Object.getPrototypeOf(this)) !== Poly.prototype) {
throw new Error("Poly subclasses cannot be subclassed");
}
}
实时示例:
class Entity { }
class Poly extends Entity {
// In Poly
constructor() {
super();
if (Object.getPrototypeOf(Object.getPrototypeOf(this)) !== Poly.prototype) {
throw new Error("Poly subclasses cannot be subclassed");
}
}
}
class Asset extends Poly {
}
class Security extends Asset {
}
// Works
try {
new Asset();
console.log("new Asset worked");
} catch (e) {
console.error(e.message);
}
// Fails
try {
new Security();
console.log("new Security worked");
} catch (e) {
console.error(e.message);
}
使用ES2015 +功能(因此TypeScript必须输出ES2015 + class
构造,而不是ES5级功能):
// In Poly
constructor() {
if (new.target && Object.getPrototypeOf(new.target) !== Poly) {
throw new Error("Poly subclasses cannot be subclassed");
}
super();
}
实时示例:
class Entity { }
class Poly extends Entity {
// In Poly
constructor() {
if (new.target && Object.getPrototypeOf(new.target) !== Poly) {
throw new Error("Poly subclasses cannot be subclassed");
}
super();
}
}
class Asset extends Poly {
}
class Security extends Asset {
}
// Works
try {
new Asset();
console.log("new Asset worked");
} catch (e) {
console.error(e.message);
}
// Fails
try {
new Security();
console.log("new Security worked");
} catch (e) {
console.error(e.message);
}
请注意,可以使用Asset
的原型而不使用其构造函数(因此也不能使用Poly
的构造函数)来规避这两个问题。例如,通过Object.create
。
在这两种情况下,如果您想更改可以和不可以继承的子类别,只需对支票进行一点更改。
答案 1 :(得分:0)
无法完成。如果一个类可以扩展基类,那么没有什么可以阻止某人编写另一个扩展相同基类的类。