有三个班级。
// in external library, which I don't want to modify
class ComponentBase {
// I want calling this to be disallowed
forceUpdate() {}
}
class ComponentBase_MyVersion extends ComponentBase {
// I want subclasses to always call this, instead of forceUpdate()
Update() {}
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// I want this to be disallowed
this.forceUpdate();
// forcing the subclass to call this instead
this.Update();
}
}
如何才能完成此操作,只更改为ComponentBase_MyVersion
?
有没有办法“隐藏”基类成员?
或许是一种覆盖定义的方法 - 比如C#中的“new”关键字 - 让我将方法定义变为至少在尝试调用时出现警告?
答案 0 :(得分:5)
OOP不允许您进行此类方法取消。您可以使用您建议的Exception在您的类上实现此功能,或使用合成:https://en.wikipedia.org/wiki/Composition_over_inheritance
示例1:
FeedListAdapter
实施例2(组合物):
class ComponentBase {
forceUpdate() {}
}
class ComponentBase_MyVersion extends ComponentBase {
Update() {}
forceUpdate() {
throw new Error("Do not call this. Call Update() instead.");
}
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// wil raise an exception
this.forceUpdate();
this.Update();
}
}
我希望我能帮忙。
答案 1 :(得分:2)
你可以在private
方法上添加forceUpdate
访问修饰符,这将导致所有子类无法访问forceUpdate
。typescript不支持包访问修饰符,但你可以通过用继承替换继承来实现这一点。
class ComponentBase {
forceUpdate() {
}
}
class ComponentBase_MyVersion {
//replace inheritance with composition.
private component: ComponentBase;
Update() {
this.component.forceUpdate();
}
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
//now subclass can't access forceUpdate method
this.Update();
}
}
symbol
方法,外部类无法访问symbol
方法。es2015.symbol
如果你的目标是es5
,因为符号是唯一的' libs.ts'无法获得该符号。
//libs.ts
let forceUpdate = Symbol("forceUpdate");
export class ComponentBase {
[forceUpdate]() {
}
}
export default class ComponentBase_MyVersion extends ComponentBase {
Update() {
this[forceUpdate]();
}
}
//test.ts
import ComponentBase_MyVersion from "./libs";
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
//now subclass can't access forceUpdate method
this.Update();
}
}
答案 2 :(得分:0)
我发现了一种似乎有用的方法 - 也就是说,当有人试图在子类实例上调用forceUpdate()
时会出现警告。
forceUpdate(_: ()=>"Do not call this. Call Update() instead.") {
throw new Error("Do not call this. Call Update() instead.");
}
现在当我写new MyComponent().forceUpdate()
时,我收到编译错误,警告消息中包含说明,告诉我改为使用Update()
。
编辑:显然这只有效,因为基类已经有了这个定义:
forceUpdate(callBack?: () => any): void;
如果相反基本方法最初没有参数定义(如在OP中),则上述解决方案不起作用。
但是,如果你有一个类似我的案例(那里有一个类似的可选属性,你可以缩小返回类型),它工作正常。 (不确定这种返回类型缩小是一个错误,还是有意的)