最近,我的老师正在教授多态性,他教导了多态性有两个方面
运行时多态性
编译时多态性
然后他向我们展示了这段代码
class A {
void ab(){
System.out.println("ab() in class A");
}
}
class B extends A {
void ab(){
System.out.println("ab() in class B");
}
}
class ObCo {
public static void main(String args[]){
A a1 = new B();
a1.ab();
}
}
输出为ab() in class B
当我尝试以下代码时,
class A {
int i = 10;
}
class B extends A {
int i = 100;
}
class ObCo {
public static void main(String args[]){
A a1 = new B();
System.out.println(a1.i);
}
}
根据前面的代码,输出应为100
但输出为10
这会在我的脑海中提出这些问题。
对这些问题的详细解答将受到高度赞赏。
答案 0 :(得分:4)
多态性仅适用于非静态非最终方法。您尝试的代码不是多态,而是field hiding(强调我的):
在类中,与超类中的字段具有相同名称的字段会隐藏超类的字段,即使它们的类型不同。在子类中,超类中的字段不能是由简单名称引用。相反,必须通过super访问该字段,这将在下一节中介绍。一般来说,我们不建议隐藏字段,因为它会使代码难以阅读。
考虑到这一点,回答你的问题:
- 多态是一个仅与Overriding方法有关的概念吗?
醇>
是
- 第一个代码块是否与多态性相关?
醇>
是
- 如果是,什么是运行时多态和编译时多态?
醇>
在Java中,默认情况下,所有非static
非final
方法都是virtual methods,因此如果子类的方法具有相同 {{ 3}}(相同的输入类型,相同的输出类型)超类,这个方法被覆盖,即使这不是你的意图。编译器甚至会发出一个警告,指出子类中的方法必须使用@Override
注释来通知其他程序员这个方法被覆盖。
在Java中,根据本教程,它被称为编译时多态到方法重载(这样一个奇怪的名字)。
4.如果没有,请给我一个看多态性的例子。
你已经有了方法覆盖(动态)的例子。
这是方法重载的另一个例子(静态):
public class Foo {
public void print(int x) {
System.out.println("Printing number: " + x);
}
public void print(String x) {
System.out.println("Printing string: " + x);
}
public static void main(String[] args) {
Foo foo = new Foo();
foo.print(5);
foo.print("5");
}
}
输出:
印刷号码:5
打印字符串:5
答案 1 :(得分:0)
- 多态是一个仅与Overriding方法有关的概念吗?
醇>
多态性仅适用于METHODS。 非静态和非最终 METHODS 。
- 第一个代码块是否与多态性相关?
醇>
实际上,在第一个块中你没有覆盖,你隐藏了ab()
方法。这是section 8.4.8.3 of the JLS中的规则,“覆盖和隐藏的要求”:
- 如果是,什么是运行时多态和编译时多态?
醇>
- 如果不是,请举例说明多态性。
醇>
比编写快速代码更好,请检查this tutorial
答案 2 :(得分:0)
您的问题:
多态是一个仅与Overriding方法相关的概念吗?
是 - Java仅对类的方法实现多态。您在数据类型上尝试它的方式不起作用。
第一个代码块是否与多态性有关?
是的,它是运行时多态性的典型例子,
如果是,什么是运行时多态和编译时多态?
您的工作示例是典型的运行时情况。我们称之为运行时,因为只有当代码实际运行时我们才能发现a1实际上是B的实例而不是A的实例
编译时多态是指由于与之关联的类型而在编译代码时选择一个方法而不是另一个具有相同名称的方法的情况。