gpt4 book ai didi

java - 面向对象范式中的方法可以被继承类中具有相同签名的方法覆盖。但是变量不能。为什么?

转载 作者:搜寻专家 更新时间:2023-10-31 19:41:09 26 4
gpt4 key购买 nike

维基百科定义 virtual methods作为:

In object-oriented programming, a virtual function or a virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature [to provide a polymorphic behavior].

根据定义,Java 中的每个非静态方法默认都是虚拟方法 final 和私有(private)方法除外。不能继承多态行为的方法不是虚方法。

Java 中的静态方法永远不能被覆盖;因此,在 Java 中将静态方法声明为 final 是没有意义的,因为静态方法本身的行为就像 final 方法一样。它们可以简单地通过具有相同签名的方法隐藏在子类中。显然是这样,因为静态方法永远不会具有多态行为:被覆盖的方法必须实现多态性,而静态方法则不是这种情况。

从上一段可以得出一个重要的结论。 C++ 中的所有方法在默认情况下都是静态的,因为 C++ 中的任何方法都不能表现出多态性,除非它们在父类(super class)中被显式声明为虚拟的。相比之下,Java 中除了 final、static 和 private 方法之外的所有方法默认都是虚方法,因为它们默认具有多态行为(在 Java 中不需要显式声明方法为虚方法,因此,Java 没有像“virtual”这样的关键字).

现在,让我们通过以下 Java 中的简单示例来证明实例变量(也包括静态变量)不能表现出多态性。

class Super
{
public int a=5;
public int show()
{
System.out.print("Super method called a = ");
return a;
}
}

final class Child extends Super
{
public int a=6;

@Override
public int show()
{
System.out.print("Child method called a = ");
return a;
}
}

final public class Main
{
public static void main(String...args)
{
Super s = new Child();
Child c = new Child();

System.out.println("s.a = "+s.a);
System.out.println("c.a = "+c.a);

System.out.println(s.show());
System.out.println(c.show());
}
}

上述代码片段产生的输出如下。

s.a = 5c.a = 6Child method called a = 6Child method called a = 6

在这个例子中,s.show()c.show() 都通过SuperChild 类型的变量分别调用 Child 类中的 show() 方法。这意味着 Child 类中的 show() 方法覆盖了 Super 类中的 show() 方法因为他们都有相同的签名。

但是,这不能应用于在两个类中声明的实例变量 a。在这种情况下,s.a 将引用 Super 类中的 a 并显示 5c.a 将引用 Child 类中的 a 并且显示 6 表示 中的 a Child 类只是隐藏(并且不会像非静态方法那样覆盖)Super 类中的 a

经过这么长的讨论,只有一个问题。为什么不覆盖实例变量(以及其他变量)?实现这种机制的特殊原因是什么?如果它们被覆盖,会有任何优势或劣势吗?

最佳答案

我认为覆盖的目的是在不更改签名的情况下更改功能。这仅与方法相关:方法可能具有相同的签名但具有不同的行为。字段只有“签名”,也仅限于类型和名称。他们没有行为,所以没有什么可以被覆盖。

无法“覆盖”字段的另一个原因是字段通常是私有(private)的(或应该是私有(private)的),因此它们实际上是类实现的血淋淋的细节。然而,方法代表类的外部接口(interface)。这个外部接口(interface)应该支持多态,以便在不改变模块之间的关系的情况下更容易地改变模块的功能。

关于java - 面向对象范式中的方法可以被继承类中具有相同签名的方法覆盖。但是变量不能。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8655098/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com