很抱歉,如果这个问题如此令人困惑,我将尝试并使其尽可能简单。
TLDR;在Typescript基类中,如何调用必须在子类中定义的子类的私有方法?
我有许多不同的Typescript子类,它们需要不同的代码来完成相同的操作:写入文件。
90%的基本代码是相同的,每个子类都有一些特定的方法实现。
因此,我采用了相同的代码并将其放在基类中,但这调用了必须在子类上实现的方法,并且最好是私有的。
这是一个例子:
abstract class BaseClass {
constructor() { }
SetOptions() {
// Set the options
// Return the options
}
GetOptions() {
// Get the options
this.WriteStuff();
}
private WriteStuff(arg1: Item, arg2: number) {}
}
class SubClass1 extends BaseClass {
private WriteStuff(arg1: SubClass1Item, number: number) {
// Write stuff in the SubClass1 way
}
}
class SubClass2 extends BaseClass {
private WriteStuff(arg1: SubClass2Item, number: number) {
// Write stuff the SubClass2 way
}
}
SubClass1Item和SubClass2Item实现Item接口。
所有子类将对SetOptions和GetOptions使用相同的代码,但是WriteStuff在每个子类中将具有个性化代码,并且需要私有,因此其他开发人员不会偶然调用它。
Typescript说我不能这样做,因为“类型具有私有属性'WriteStuff'的单独声明”。而且Typescript不会让我不要在BaseClass中声明该方法,因为这样我将调用一个不存在但将存在于子类中的方法。
这可能吗?
private
方法只能在类本身中访问,而不能在任何后代中访问。您不能拥有一种private abstract
方法,因为这是一个内在的矛盾-如果子孙需要实现它,则不是private
。
您要使用protected
修饰符。根据文档:
该
protected
修改的行为很像private
,不同的是声明成员修改protected
也派生类中进行访问。
您要声明BaseClass
所有混凝土必须实现一个WriteStuff()
方法。这是一种abstract
方法,意味着它没有实现BaseClass
,必须被覆盖。
在您的子孙中,实现WriteStuff
必须是protected
而不是private
。
abstract class BaseClass {
/* .... */
protected abstract WriteStuff(arg1: Item, arg2: number): void;
}
class SubClass1 extends BaseClass {
protected WriteStuff(arg1: SubClass1Item, number: number) {
// Write stuff in the SubClass1 way
}
}
您的类并不共享相同的签名,因为它们arg1
传递给的第一个参数的类型不同WriteStuff
。您最有可能希望根据或其他类型的值使用通用类arg1
。
如果SubClass1Item
并且SubClass2Item
不扩展,Item
那么您绝对需要一个通用类,因为WriteStuff
子类中的实现将无法分配给基类。
如果它们确实扩展了,Item
那么在当前设置下您将不会遇到打字稿错误。但是,当您this.WriteStuff
从GetOptions()
in调用时,可能会出现运行时错误BaseClass
。如何BaseClass
知道Item
它所具有的是否可分配给或中Item
期望的子类型?这是泛型可以提供帮助的地方。SubClass1
SubClass2
我们BaseClass
基于变量创建泛型ItemType
。我们可以要求所有ItemType
变量都扩展一个共享库Item
,但是我们不必这样做。
子类本身不是泛型类。他们将扩展其所需BaseClass
的特定版本ItemType
。
abstract class BaseClass<ItemType extends Item> {
/* ... */
GetOptions(item: ItemType) {
// Get the options
this.WriteStuff(item, 5);
}
protected abstract WriteStuff(arg1: ItemType, arg2: number): void;
}
class SubClass1 extends BaseClass<SubClass1Item> {
protected WriteStuff(arg1: SubClass1Item, number: number) {
// Write stuff in the SubClass1 way
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句