这是我的演示代码:
class First {
x: string;
y: string;
constructor()
{
}
setValue(x: string, y: string): void {
this.x = x;
this.y = y;
console.log("setValue In A value of x and y:", this.x, this.y);
}
getValue(): void {
console.log("getValue In A value of x and y:", this.x, this.y);
}
}
class Second extends First {
x: string = '5';
z: number;
constructor() {
super();
}
setValue(z: number, y: string) {
this.z = z;
this.y = y;
return super.setValue(this.x, this.y);
}
}
我有两个班,第一和第二。 但是在第二课中,我遇到了错误
Property 'setValue' in type 'Second' is not assignable to the same property in base type 'First'. Type '(z: number, y: string) => void' is not assignable to type '(x: string, y: string) => void'. Types of parameters 'z' and 'x' are incompatible. Type 'string' is not assignable to type 'number'
我尝试了一些可能的解决方案,方法是在Class first方法中将类型指定为“ any” 还尝试了另一个补丁,方法是在Class Second中将联合类型指定为z:string |数字
但是两种解决方案都是解决该问题的方法,但不能解决原始问题,因为我们可以传递字符串或数字,但实际上,它只接受字符串。 如果假设该方法仅接受一个参数,则清除更多内容,则上述解决方案均无效。
我希望我的问题很清楚。
答案 0 :(得分:1)
问题在于您尝试做的事情违反了OOP原则。假设允许您想要的重载,请考虑以下代码:
let f: First = new Second() // Assign a derived class to a base type reference
f.setValue("Not a number", "y") // Second is getting a string insead of a number
在Second
以上的代码中,由于我们正在通过基类引用进行调用,因此将以string
而不是数字作为第一个参数。
一种解决方案是既保留原始签名,又添加带有数字的签名,并确保两者均按预期工作:
class First {
x: string;
y: string;
constructor()
{
}
setValue(x: string, y: string): void {
this.x = x;
this.y = y;
console.log("setValue In A value of x and y:", this.x, this.y);
}
getValue(): void {
console.log("getValue In A value of x and y:", this.x, this.y);
}
}
class Second extends First {
x: string = '5';
z: number;
constructor() {
super();
}
setValue(x: string, y: string)
setValue(z: number, y: string)
setValue(xz: string | number, y: string) {
if (typeof xz == 'number') {
this.z = xz; // xz is number so we got called with z
this.y = y;
return super.setValue(this.x, this.y);
} else {
// xz is string so we got called with x
return super.setValue(xz, y);
}
}
}
let f: First = new Second() // Assign a derived class to a base type reference
f.setValue("Not a number", "y") // Works as expected now
通常,在派生类时,可以添加到该类的公共签名,但是不能从中获取,因为那样会破坏OOP的租户,您可以安全地将派生类分配给基类引用。 / p>
注意:打字稿的类型非常灵活,您可以进行某种类型的手术,从setValue
中删除First
,以便在{ {1}}。我可以提供这样的解决方案,但强烈建议您反对。