简单的现实世界示例,不应该覆盖方法?

时间:2011-10-18 12:55:11

标签: java

我正在为关键字final做准备。它用于定义无法在其子类中重写的方法。

但我有一个问题,就是找一些真正好的简单现实世界的例子,我想避免在子类中重写一个方法。

任何提示?

5 个答案:

答案 0 :(得分:2)

final 方法有时可以由编译器内联到子类中,从而获得较小的性能优势。

至于何时希望避免子类提供自己的方法定义的示例,只要方法的定义对于对象的持久性或系统的性能至关重要,它就应该是最终的。

应该仔细考虑从构造函数调用的方法,通常它们必须是最终的,以确保强大的类定义。

真实世界的例子总是多开发者环境。如果你为一家处理信用卡信息的公司工作,并且你有一个做重要事情的java类,你不希望一些实习生意外覆盖一个重要的方法,所以你建立系统的方式甚至其他开发人员也不能它不安全。

也不要忘记最后的课程和最后的字段!

答案 1 :(得分:2)

作为一个人为的例子:您可能希望您的类通知观察对象某些状态发生了变化。您希望人们对您的类进行子类化,以便能够覆盖此状态的更改方式,但不会发送这些事件。

public class Womble {
    public String fluff;

    // notify listeners that the value of 'fluff' is changing
    private void onFluffChanging() {
        //…
    }

    // Others can override this method
    protected void setFluffImpl(String value) {
        fluff = value;
    }

    // But not this one, so the notification always gets sent
    public final void setFluff(String value) {
        onFluffChanging();
        setFluffImpl(value);
    }
}

一般情况下,当你想确保你的类的某些行为不会被子类“删除”时,你会使用final。有些人还喜欢默认使用final作为一切,以防止任何形式的意外使用他们的代码 - 唯一没有最终的类和方法是他们明确打算进行子类化的。后者在制作将被大量重用的代码时非常有用,特别是在制作将通过继承其类重复使用的代码时。

答案 2 :(得分:2)

要在这里平衡其他答案 - 确定的好答案 - 请记住,在实际使用中,通常很难准确预测将来如何使用课程。将final添加到您的代码中是因为您觉得某些内容不应该更改,这可能会增加使用该代码的人未来的挫败感,并且final总是可以被绕过创意开发人员以这种或那种方式。这只是一个问题,你想要多少诱惑他/她这样做。如果涉及到这一点,那么你最好希望那个人真的知道他或她在做什么。

答案 3 :(得分:2)

几乎所有使用Template Method模式的框架和库代码都有例子。

例如,在SwingWorker中,包括execute()run()在内的许多方法都是最终的,但这些方法调用的方法doInBackground()是抽象的,并且打算由子类,而其他方法有默认实现,但不是最终的,所以允许重写。

答案 4 :(得分:2)

非抽象类的equals()方法的实现必须用final修饰符标记。这个陈述可以通过示例(标准库中的实际代码)轻松证明:

public class Date {

     private transient long fastTime;

     ....

     public long getTime() {
         return getTimeImpl();
     }

     ....

     public boolean equals(Object obj) {
         return obj instanceof Date && getTime() == ((Date) obj).getTime();
     }
}

public class Timestamp extends java.util.Date {

    public boolean equals(java.lang.Object ts) {
        if (ts instanceof Timestamp) {
        return this.equals((Timestamp)ts);
        } else {
        return false;
        }
    }

    public boolean equals(Timestamp ts) {
        if (super.equals(ts)) {
            if  (nanos == ts.nanos) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

这意味着违反了equals()合同:

date.equals(timestamp) == true

timestamp.equals(date) == false