默认情况下虚拟比非虚拟好的原因有两个。
关于oop有用性的主要原则是
里氏代换原则
,
多态性
和
晚绑定
. 我一直使用策略模式,因此我希望我的方法是虚拟的。如果你是开/闭原理的爱好者,你应该更喜欢Java哲学。您应该能够在不更改源代码的情况下更改行为。可以使用依赖注入和虚拟方法来实现这一点。
如果调用非虚拟方法,则需要从代码中知道调用的是哪个类方法。.net的缺陷是你无法从代码中知道这一点。
虚拟唯一方法的另一个好处是测试代码容易得多,因为您可以制作(或第三方)类的模拟。用Java进行测试在Java中是很容易的。
例子
在Java中,如果将ClassB定义为
public class ClassB extends ClassA {
@Override
public void run() {
}
}
对象
ClassA obj=new ClassB();
如果调用obj.run(),您如何知道该代码是遵循多态打开/关闭原则的规则,还是将对与ClassA相关的方法进行编码?在爪哇,你会知道总是存在多态性。更容易制作mock,更容易扩展类并遵循liskov替换原则。
另一方面,静态方法被绑定到一个类,所以如果你想调用一个与类相关的方法,你可以定义这样的方法:
public static run(ClassA obj)
你可以用它来称呼它
ClassB obj=new ClassB();
ClassA.run(obj);
从代码中,您将知道您调用的方法是在classa中定义的,而不是在classb中定义的。同样,在这种情况下,您将不会有虚拟方法的开销。(注意,在许多情况下,jit还将减少虚拟方法的开销)。
对于c_来说,如果使方法非虚拟的原因是能够在子类中定义它,但不涉及多态性,那么您可能没有真正的原因而进行子类化。
如果是设计的话,我建议尽可能把这个类密封在(Java中的最后一个)而不是单独的方法。
jon skeet说,在c中,类在默认情况下应该被密封,因为方法在默认情况下也是非虚拟的。约书亚布洛赫说,你应该设计继承或禁止它(使类最终)。设计师选择了一种不一致的混合方法。