我想重写一个方法并将不同的参数类型传递给它:
class Base {
public myMethod(myString: string): undefined {
return;
}
}
class Child extends Base {
public myMethod(myNumber: number): undefined {
return super.myMethod(String(myNumber));
}
}
然而,这会产生一个打字错误:
“
”类型中的属性“”myMethod“”不能赋值给基类型“”base“”中的同一属性。“”类型'(myNumber: number) => undefined‘不可分配给类型'(myString: string) => undefined’。参数'myNumber‘和'myString’的类型不兼容。类型'string‘不可赋值给类型'number’。
有没有办法在不产生打字错误的情况下做到这一点?
发布于 2018-06-07 10:38:08
正如其他人所提到的,这不是一个好主意,因为您破坏了Liskov替换。
您可以轻松地提供一个同时接受string
和number
的覆盖。这使得您的类仍然可以在需要基类的任何地方使用。
class Base {
public myMethod(myString: string): undefined {
return;
}
}
class Child extends Base {
public myMethod(myNumberOrString: number | string): undefined {
if (typeof myNumberOrString === 'number') {
return super.myMethod(String(myNumberOrString));
} else {
return super.myMethod(myNumberOrString);
}
}
}
发布于 2020-10-02 17:40:41
似乎有一种方法可以工作,即使是对于返回类型,至少在使用中间类的TypeScript v4.02中是这样。
但是这违反了Liskov替换原则,因为它改变了返回类型,并且没有处理参数是字符串的情况。
因此,仅仅为了了解而提到它是值得的,但在代码审查中,我不会接受这种攻击,因为子类应该能够在不破坏功能的情况下替换基类。
class Base {
public myMethod(myString: string): string {
return myString + myString;
}
}
// weaken
// inspired by comment here: https://github.com/microsoft/TypeScript/issues/3402#issuecomment-385975990
class Interim extends Base {
public myMethod(x: any): any { return super.myMethod(x); }
}
class Child extends Interim {
public myMethod(myNumber: number): number {
return myNumber * myNumber;
}
}
// we can have a helper/utility for this
function weaken(klass: { new(...args: any[]): any; }, key: string) {
return class extends klass {
[key](...args: any[]) { super[key](...args); }
}
}
class ChildOther extends weaken(Base, 'myMethod') {
public myMethod(myNumber: number): number {
return myNumber * myNumber;
}
}
console.log((new Child()) instanceof Base); // true
console.log((new ChildOther()) instanceof Base); // true
console.log(new Base().myMethod('str')); // strstr
console.log(new Child().myMethod(3)); // 9
console.log(new ChildOther().myMethod(3)); // 9
发布于 2021-09-26 22:31:32
只要创建第三个BaseClass
并从它扩展两个类,就可以很容易地做到这一点。只需确保具有不同参数的函数仅在扩展类中定义(这样它们就不会重叠)。下面是它实际应用的一个简单示例(我的函数不同,它的名称是specialFunction):
class BaseClass { // FirstClass and SecondClass both extend this class
constructor() {
this.name = ""
}
name: string
}
class FirstClass extends BaseClass {
specialFunction(name: string) { // <- this only has one parameter
this.name = name
}
}
class SecondClass extends BaseClass {
constructor() {
super()
this.num = 0
}
specialFunction(name: string, num: number) { // <- this has two parameters
this.name = name
this.num = num
}
num: number
}
https://stackoverflow.com/questions/50729485
复制相似问题