废弃最终超类方法?

9
如何表示超类的最终方法已经过时?
//Class a out of my control
class A{
    public final void foo(){
     ...
    }
}

class B extends A{
   public void fooAlternative(){...}

   //deprecate foo?
}

背景: 在扩展JavaFX API时,我们面临几个禁止我们随意更改的final方法。 有时这是必需的,我找到的唯一合适的解决方案是创建一个附加方法。在这种情况下,废弃A提供的方法将使程序员意识到存在不同的替代方法。
包装对象不是可行的选择,因为多态性需要继承。

3
如果我理解正确,您希望在尝试调用某些方法时得到警告/错误提示。也许您需要一种可配置的静态代码分析工具。 - Andreas
你是说你无法编辑 A类 吗? - Johannes
@Xydez 是的,完全正确。 - Kilian
2
为什么你说包装对象不是可行的选项?你可以创建一个AWrapper而不需要扩展A。所有方法将具有与A相同的方法名称和签名,并且将简单地委托给A的方法。 foo方法将被注释为@Deprecated,并且我个人甚至会抛出一个AssertionError... 我不明白这如何影响你的多态性。 - Eugene
2
那么类A是一些JavaFX模型/组件,其方法由其他框架模型/组件调用。您想通过重写方法来装饰它的行为,但这是不可能的,因为这些方法是final的,所以您决定实现fooAlternative(),但框架无法调用“替代”方法。那么这些“替代”方法的用例是什么? - matoni
你的子类是覆盖了某种行为,还是只是自定义一个控件?如果是后者,继承并不是正确的方式。一个继承了java.lang.Object并包含一个Node属性(或者一个简单的工厂类)的类才是正确的方法。 - VGR
1个回答

1
为了让您更清楚地理解 Eugene 在评论中所说的内容,以下是一个更明确的例子:
import javafx.scene.control.Label;

/**
 * Example as described by @Eugene
 */
public class AWrapper {

    private final Label wrapped = new Label();

    public AWrapper() {

    }

    // Implement only what you **want** to expose

    // Assume setText as "deprecated"

    /**
     *
     * @param text The text
     * @see Label#setText(String)
     */
    @Deprecated
    private void setText(final String text) {
        wrapped.setText(text);
    }

    /**
     * Alternative to {@link AWrapper#setText(String)}.
     *
     * Does some extra work.
     *
     * @param text New text
     */
    private void text(final String text) {
        System.out.println("New Label text: " + text);

        wrapped.setText(text);
    }

}

不要使用继承,而是使用组合,并且只暴露所需的API(如果有时间,则可以暴露完整的原始API)。这基本上让您控制了“超级”元素。没有办法编辑超类的元信息,您也不应该编辑它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接