在子类中密封方法,因此孙子不能覆盖它

Posted

技术标签:

【中文标题】在子类中密封方法,因此孙子不能覆盖它【英文标题】:Making a method sealed in child class, so grandchildren cannot override it 【发布时间】:2021-12-27 08:10:46 【问题描述】:

有一个abstract class A 为特定功能提供基本工具。 A 类的一个子类,称为 abstract class B,是 A 提供工具的问题的一个特定子集,但有更多限制。

所以,我需要避免B 的子代覆盖某个方法,而B 本身从A 覆盖它,A 的其他子代也可以覆盖它。

这是我在代码中想象的东西:

abstract class A 
    public abstract foo();
    // ...


abstract class B extends A 
    public override foo() 
        // ...
    


class CofB extends B 
    // This one shouldn't be able to override foo()


class XofA extends A 
    // But this one should still be able to override foo(), 
    // as it's extending A directly

在 C# 中,我们可以通过在 B 中将 foo() 标记为 override sealed 来做到这一点。

但是由于 TypeScript 不支持这一点,有什么解决方法可以达到相同的结果?或者如果没有,我怎样才能改变设计来达到同样的效果?

【问题讨论】:

***.com/questions/42814649/… @AlekseyL。我在发布这个问题之前看到了这一点。不幸的是,该线程中描述的解决方法[将方法创建为父级中的只读变量]似乎不适用于密封“孙子”的情况(A 允许覆盖,但B 密封它所以C不能再覆盖它了)。 是的,解决方法根本不起作用,但恐怕这方面没有什么新东西.. 【参考方案1】:

目前,我已经确定了运行时检查以确保该方法未被覆盖。

这没有在编译时进行安全检查的好处,但至少这会失败并显示明确的错误消息,并避免未定义的行为导致难以调试的错误。 p>

这就是我所做的:

abstract class A 
    public abstract foo();
    // ...


abstract class B extends A 
    public override foo() 
        // ...
    


    constructor() 
        super();
        
        if (this.foo !== B.prototype.foo) 
            throw new Error("Class is overriding foo, which is not allowed for children of B.");
        
    


class CofB extends B 
    
    // This compiles, but throws an error when trying to create an
    // instance of CofB; e.g. var x = new CofB();
    public override foo() 
        // ...
    


class XofA extends A 

    // This works properly.
    public override foo() 
        // ...
    

当然,以一种导致编译时检查的方式实现这一点会好得多;但到目前为止我找不到。

【讨论】:

以上是关于在子类中密封方法,因此孙子不能覆盖它的主要内容,如果未能解决你的问题,请参考以下文章

重写(覆盖,Override)和重载(Overload)的区别

java中方法的重载和覆盖分别要满足的条件

3.10学习

JAVA中方法和变量在继承中的覆盖和隐藏

final关键字

final 关键字