如何在基类方法中调用子类方法?
How do you call a subclass method in the baseclass method?
很抱歉,如果这个问题如此令人困惑,我将尝试尽可能简单。
TLDR; 如何在 Typescript baseclass 中调用必须在子class?
我有许多不同的 Typescript 子class需要不同的代码来做同样的事情:写入文件。
90% 的基本代码是相同的,每个子class.
有一些方法的具体实现
所以我采用了相同的代码并将其放在基 class 中,但是调用的方法必须在子 class 上实现并且最好是私有的。
这是一个例子:
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 接口。
所有子classes 将对 SetOptions 和 GetOptions 使用相同的代码,但 WriteStuff 将在每个子class 中具有个性化代码并且需要是私有的,因此不会被其他人调用开发者意外。
Typescript 说我不能这样做,因为“类型有单独的私有声明 属性 'WriteStuff'”。 Typescript 不允许我不在 BaseClass 中声明方法,因为我正在调用一个不存在但将存在于 subclass.
中的方法
这可能吗?
私有与受保护
private
方法只能在 class 本身中访问,不能在任何后代中访问。你不能有一个 private abstract
方法,因为这是一个内在的矛盾——如果后代需要实现它,那么它就不是 private
.
您想使用 protected
修饰符。每 the docs:
The protected
modifier acts much like the private
modifier with the exception that members declared protected
can also be accessed within deriving classes.
您想在 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 类型
您的 classes 并不都共享相同的签名,因为它们每个都具有不同的第一个参数 arg1
传递给 WriteStuff
的类型。您很可能希望根据 arg1
或其他值的类型使用 generic class。
如果 SubClass1Item
和 SubClass2Item
不扩展 Item
那么你绝对 需要 一个通用的 class 因为实现subclasses 中的 WriteStuff
不能分配给 base。
如果他们做扩展Item
,那么您将不会在当前设置中遇到打字稿错误。但是,当您从 BaseClass
中的 GetOptions()
调用 this.WriteStuff
时,可能会出现运行时错误。 BaseClass
如何知道它拥有的 Item
是否可分配给 SubClass1
或 SubClass2
中预期的 Item
子类型?这是泛型可以提供帮助的地方。
我们使 BaseClass
成为基于变量 ItemType
的泛型。我们可以要求所有 ItemType
变量扩展一个共享基 Item
,但我们不必这样做。
子class本身不是通用的class。他们将使用他们需要的特定 ItemType
扩展 BaseClass
版本。
代码
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
}
}
JavaScript 最近支持 private field declarations including private instance methods。在那里,一种可能的方法是为基础 class' 超级调用提供 sub class 特定实现 ...
class BaseClass {
// default implementation of private instance method.
#writeStuff = () => void 0;
constructor(writeStuff) {
// at instantiation time, if appropriate, ...
if (typeof writeStuff === 'function') {
// ... overwrite the default implementation.
this.#writeStuff = writeStuff;
}
}
// prototypal method ...
getOptions(...args) {
// ... with access to a private instance method.
this.#writeStuff(...args);
}
setOptions() {/* ... */}
}
class SubClass1 extends BaseClass {
constructor() {
const writeStuff = (...args) =>
// Write stuff in the SubClass1 way
console.log(`SubClass1 [...args] : ${ [...args] }`);
super(writeStuff);
// do other things
}
}
class SubClass2 extends BaseClass {
constructor() {
const writeStuff = (...args) =>
// Write stuff in the SubClass2 way
console.log(`SubClass2 [...args] : ${ [...args] }`);
super(writeStuff);
// do other things
}
}
const objA = new SubClass1;
const objB = new SubClass2;
objA.getOptions('foo', 'bar');
objB.getOptions('baz', 'biz');
.as-console-wrapper { min-height: 100%!important; top: 0; }
很抱歉,如果这个问题如此令人困惑,我将尝试尽可能简单。
TLDR; 如何在 Typescript baseclass 中调用必须在子class?
我有许多不同的 Typescript 子class需要不同的代码来做同样的事情:写入文件。
90% 的基本代码是相同的,每个子class.
有一些方法的具体实现所以我采用了相同的代码并将其放在基 class 中,但是调用的方法必须在子 class 上实现并且最好是私有的。
这是一个例子:
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 接口。
所有子classes 将对 SetOptions 和 GetOptions 使用相同的代码,但 WriteStuff 将在每个子class 中具有个性化代码并且需要是私有的,因此不会被其他人调用开发者意外。
Typescript 说我不能这样做,因为“类型有单独的私有声明 属性 'WriteStuff'”。 Typescript 不允许我不在 BaseClass 中声明方法,因为我正在调用一个不存在但将存在于 subclass.
中的方法这可能吗?
私有与受保护
private
方法只能在 class 本身中访问,不能在任何后代中访问。你不能有一个 private abstract
方法,因为这是一个内在的矛盾——如果后代需要实现它,那么它就不是 private
.
您想使用 protected
修饰符。每 the docs:
The
protected
modifier acts much like theprivate
modifier with the exception that members declaredprotected
can also be accessed within deriving classes.
您想在 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 类型
您的 classes 并不都共享相同的签名,因为它们每个都具有不同的第一个参数 arg1
传递给 WriteStuff
的类型。您很可能希望根据 arg1
或其他值的类型使用 generic class。
如果 SubClass1Item
和 SubClass2Item
不扩展 Item
那么你绝对 需要 一个通用的 class 因为实现subclasses 中的 WriteStuff
不能分配给 base。
如果他们做扩展Item
,那么您将不会在当前设置中遇到打字稿错误。但是,当您从 BaseClass
中的 GetOptions()
调用 this.WriteStuff
时,可能会出现运行时错误。 BaseClass
如何知道它拥有的 Item
是否可分配给 SubClass1
或 SubClass2
中预期的 Item
子类型?这是泛型可以提供帮助的地方。
我们使 BaseClass
成为基于变量 ItemType
的泛型。我们可以要求所有 ItemType
变量扩展一个共享基 Item
,但我们不必这样做。
子class本身不是通用的class。他们将使用他们需要的特定 ItemType
扩展 BaseClass
版本。
代码
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
}
}
JavaScript 最近支持 private field declarations including private instance methods。在那里,一种可能的方法是为基础 class' 超级调用提供 sub class 特定实现 ...
class BaseClass {
// default implementation of private instance method.
#writeStuff = () => void 0;
constructor(writeStuff) {
// at instantiation time, if appropriate, ...
if (typeof writeStuff === 'function') {
// ... overwrite the default implementation.
this.#writeStuff = writeStuff;
}
}
// prototypal method ...
getOptions(...args) {
// ... with access to a private instance method.
this.#writeStuff(...args);
}
setOptions() {/* ... */}
}
class SubClass1 extends BaseClass {
constructor() {
const writeStuff = (...args) =>
// Write stuff in the SubClass1 way
console.log(`SubClass1 [...args] : ${ [...args] }`);
super(writeStuff);
// do other things
}
}
class SubClass2 extends BaseClass {
constructor() {
const writeStuff = (...args) =>
// Write stuff in the SubClass2 way
console.log(`SubClass2 [...args] : ${ [...args] }`);
super(writeStuff);
// do other things
}
}
const objA = new SubClass1;
const objB = new SubClass2;
objA.getOptions('foo', 'bar');
objB.getOptions('baz', 'biz');
.as-console-wrapper { min-height: 100%!important; top: 0; }