Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么方法在Java中默认为虚拟的,而在C#中默认为非虚拟的?_C#_Java_Oop - Fatal编程技术网

为什么方法在Java中默认为虚拟的,而在C#中默认为非虚拟的?

为什么方法在Java中默认为虚拟的,而在C#中默认为非虚拟的?,c#,java,oop,C#,Java,Oop,在Java中,默认情况下方法是虚拟的;C#正好相反 哪个更好?每种方法的优缺点是什么 有几个原因。一是 演出我们可以这样观察 人们用Java编写代码,却忘记了 将他们的方法标记为最终结果。 因此,这些方法是虚拟的。 因为它们是虚拟的,所以它们不是 表现也很好。只是 与性能相关的性能开销 作为一种虚拟的方法。那是一个 问题 一个更重要的问题是版本控制。 关于这个问题,有两个学派 虚拟方法。学术学校 思想的中心说:“一切都应该 虚拟的,因为我可能想 总有一天会推翻它 思想流派,来自 构建在中运行的真

在Java中,默认情况下方法是虚拟的;C#正好相反

哪个更好?每种方法的优缺点是什么

有几个原因。一是 演出我们可以这样观察 人们用Java编写代码,却忘记了 将他们的方法标记为最终结果。 因此,这些方法是虚拟的。 因为它们是虚拟的,所以它们不是 表现也很好。只是 与性能相关的性能开销 作为一种虚拟的方法。那是一个 问题

一个更重要的问题是版本控制。 关于这个问题,有两个学派 虚拟方法。学术学校 思想的中心说:“一切都应该 虚拟的,因为我可能想 总有一天会推翻它 思想流派,来自 构建在中运行的真实应用程序 “现实世界,”他说,“我们必须 对我们的产品要非常小心 虚拟的。”

当我们在一个虚拟的 平台,我们做了很多 关于未来发展的承诺 未来。对于非虚方法,我们 答应我当你打电话的时候 方法,x和y将发生。当我们 在API中发布一个虚拟方法,我们 你打电话的时候不仅要保证 这个方法,x和y将会发生。我们 也要保证当你超越 这个方法,我们将在这里调用它 关于 这些其他人和国家将 在这个和那个不变量中

每次你在API中说虚拟, 您正在创建回调挂钩。作为 操作系统或API框架设计器, 你必须非常小心 那个您不希望用户覆盖 并在任意一点上钩 API,因为您不必 做出那些承诺。人们可能会 不完全理解他们的承诺 当他们做东西的时候,他们在做什么 虚拟的


Java的方式更简单,默认情况下C#的方式更细粒度、更安全、更高效。啤酒持有者认为哪个更好。

.Net迫使程序员定义哪些函数可以被重写,而Java函数在默认情况下可以被重写,除非使用最后一个关键字


若您是Java的坚定拥护者,您可能倾向于支持Java方式。最好允许类被扩展,方法被重写,这样基本功能/代码就不会被触及。因此,我支持/更喜欢Java方式。如果我从另一个角度来看这个问题,我的观点可能正好相反。

这是一个时间上的扰动。C++使用虚拟关键字和最终作为默认值。 遵循C++,并尝试着最好地改进它的缺点。过度使用继承的危险尚未显现,因此Java选择使用final关键字和virtual作为默认值


C#遵循Java,具有事后诸葛亮的优点。安德斯在观察java的经验之后,选择回到C++约定。

一如既往,有利弊。C#使得实施变得更加困难,但正如其他人所提到的,事后诸葛亮可能是20/20。归根结底,这取决于您是否认为类必须为扩展而设计,还是仅仅为不可预见的行为修改而打开。在设计语言时,这是一个很难回答的问题。我认为行业经验倾向于C#所采取的更为保守的方法。

有两个主要原因,为什么默认情况下虚拟比非虚拟好得多

  • OOP有用性的主要原则是Liskov替换原则多态性后期绑定。我一直在使用策略模式,为此我希望我的方法是虚拟的。如果您是开放/封闭原则的爱好者,您应该更喜欢Java哲学。您应该能够在不更改源代码的情况下更改行为。您可以使用依赖项注入和虚拟方法来实现这一点
  • 如果您调用非虚拟方法,那么您希望从代码中知道您正在调用哪个类方法。net的缺陷在于,您无法从代码中知道这一点
  • 仅虚拟方法的另一个好处是,测试代码要容易得多,因为您可以模拟(或第三方)类。用Mockito进行测试在Java中非常容易
  • 例子 在Java中,如果将ClassB定义为

    public class ClassB extends ClassA {
        @Override 
        public void run() {
        }
    }
    
    和对象

    ClassA obj=new ClassB();
    
    如果调用obj.run(),您如何知道该代码是否遵循多态打开/关闭原则的规则,或者它将编写与ClassA相关的方法?在Java中,您将知道始终存在多态性。制作mock更容易,扩展类和遵循Liskov替换原则也更容易

    另一方面,静态方法被绑定到一个类,因此如果您想调用一个与ClassA相关的方法,您可以这样定义该方法:

    public static run(ClassA obj)
    
    你可以把它叫做

    ClassB obj=new ClassB();
    ClassA.run(obj);
    
    从代码中,您将知道您正在调用的方法是在ClassA中定义的,而不是在ClassB中定义的。在这种情况下,您也不会有虚拟方法的开销。(请注意,在许多情况下,JIT还将减少虚拟方法的开销)

    对于C#,如果使方法成为非虚拟方法的原因是能够在子类中定义它,但不涉及多态性,那么您可能没有真正的原因而进行子类化

    如果是为了设计,如果可能的话,我建议将类密封(java中的final)而不是单独的方法


    Jon Skeet说,在C#中,类在默认情况下应该被密封,因为方法在默认情况下也是非虚拟的。Joshua Bloch说您应该为继承而设计,或者禁止继承(使类成为最终类)。C#设计师选择了一种不一致的混合方法。

    我认为这与运行时有关。我也在等待答案+1什么是“虚拟”?我用java编写代码,我有