我想在抽象类中重载一个抽象方法,如下所示:
abstract class Animal {
public abstract communicate(sentence: string): void;
public abstract communicate(notes: string[]): void;
}
class Human extends Animal {
public communicate(sentence: string): void {
// Do stuff
}
}
class Bird extends Animal {
public communicate(notes: string[]): void {
// Do stuff
}
}
但是,Typescript会出错,说明我错误地扩展了基类(Animal)
我做错了吗?就像期待一些工作,根据OOP无论如何都可以工作?还是打字稿不支持?
注意:与此示例不同,参数的类型可以是完全不同的类型。
答案 0 :(得分:2)
该抽象类需要实现两个方法签名。这两个方法签名是:
public abstract communicate(sentence: string): void;
public abstract communicate(notes: string[]): void;
它们可以这样实现:
class Human extends Animal {
communicate(sentence: string); // optional overload signature
communicate(notes: string[]); // optional overload signature
communicate(sentenceOrNotes: string | string[]) {
// Do stuff
}
}
最终的签名是实施签名。它需要与需要实现的方法签名兼容。
关于子类的注意事项
子类需要与基础兼容,以便在您执行时...
const animal: Animal = new Bird();
...子类应该能够处理两个调用:
animal.communicate("some sentence");
animal.communicate(["notes", "more notes"]);
在这种情况下,根据通信形式(或使用mixins)创建单独的接口可能更合适:
interface CommunicatesWithSentences {
communicate(sentence: string);
}
class Human extends Animal implements CommunicatesWithSentences {
communicate(sentence: string) {
// Do stuff
}
}
答案 1 :(得分:2)
与@DavidSherret一样,子类必须实现所有抽象类重载,而不仅仅是其中之一。因此,您无法使用抽象类重载来实现您想要的功能。
由于你想要的是Bird
和Human
具有不同的communicate()
param类型,由编译器强制执行,我将使用类型约束的泛型类型参数:
abstract class Animal<C extends string | string[]> {
public abstract communicate(communication: C): void;
}
class Human extends Animal<string> {
public communicate(sentence: string): void { }
}
class Bird extends Animal<string[]> {
public communicate(notes: string[]): void { }
}
class Bynar extends Animal<boolean> { // Error: 'boolean' does not satisfy the constraint 'string | string[]'.
public communicate(bit: boolean): void { }
}
const human = new Human();
human.communicate("hello"); // OK
human.communicate(["hello"]); // Error
const bird = new Bird();
bird.communicate("hello"); // Error
bird.communicate(["hello"]); // OK
提示:您也可以在此处使用TS 2.3 default type arguments。
答案 2 :(得分:0)
您可以这样做,希望对您有用。
export abstract class BaseComponent {
constructor(protected valueName: string) {
}
protected doSomethingMoreButOptional(config: IConfig): void { }
protected doSomething() {
if (valueName === 'derived') {
this.doSomethingMoreButOptional(new Config());
}
}
}
export class DerivedComponent extends BaseComponent {
private _xxx: any[];
private _yyy: any[];
constructor() {
super('derived');
super.doSomething();
}
protected doSomethingMoreButOptional(config: IConfig): void {
switch (config.ABC) {
case 'xxx':
config.options = this._xxx;
break;
case 'yyy':
config.options = this._yyy;
break;
default:
return;
}
}
}