如何声明只有抽象类可以继承的基类?

时间:2019-02-27 11:18:09

标签: typescript

基类:

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))

2 个答案:

答案 0 :(得分:1)

我可以考虑在运行时上执行此操作的方法。我怀疑它可以在TypeScript编译时完成。

我的理解是您想禁用间接子类。因此Asset可以,因为它是PolyPoly <-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)

无法完成。如果一个类可以扩展基类,那么没有什么可以阻止某人编写另一个扩展相同基类的类。