public class Base { private String name = "base"; public Base() {
tellName();
printName(name);
} public void tellName() {
System.out.println("Base tell name:" + name);
} public void printName(String name) { System.out.println("Base print name:" + name);
}
}public class Derived extends Base { private String name = "Derived"; public Derived() {
tellName();
printName(name);
} public void tellName() {
System.out.println("Derived tell name:" + name);
} public void printName(String name) { System.out.println("Derived print name:" + name);
} public static void main(String[] args) {
Derived derived = new Derived(); }}针对程序跑出的结果,思考许久,想了2种解释,一种是多态,一种是程序空间的解释,貌似稍微改一下程序就无法解释了。
还求大神给分析分析这个到底是如何执行的?java多态
//private String name = "base";
int name = 2;
public Base() {
printName(name);
tellName();
}
public void tellName() {
System.out.println("Base tell name:" + name);
}
public void printName(int name) {
System.out.println("Base print name:" + name);
}
}
public class Derived extends Base {
//private String name = "Derived";
int name = 3;
public Derived() {
tellName();
printName(name);
}
public void tellName() {
System.out.println("Derived is name:" + name);
}
public void printName(int name) {
System.out.println("Derived print name:" + name);
}
public static void main(String[] args) {
Derived derived = new Derived();
}
}
Hi,谢谢你的回答
针对你的回家,我有两个不明白的地方:
1.“又因为你在子类中重写了父类的方法,所以会调用子类的方法。这时就是多态的形式了。”这句话你能详细解释下原理吗?因为是多态,那么就是由调用tellName方法的对象在运行时决定到底调用父类还是子类的tellName方法,那么这个对象我认为是this引用。那么是否是在Derived构造器开始执行的时候,跳转到执行Base的构造器时,将this引用传递过去了?我觉得我这种理解是没有道理的,还请指教这里的多态到底是怎么一回事?
2.如果我把Base的tellName的public改为private,那么对于tellName方法的多态条件就不在成立,此时又该如何解释呢?谢谢
开始分析:程序首先调用父类的构造器
public Base() {
tellName();//这里tellName 在子类 Driver中被重写了所以执行的是子类的tellname和 printName 有疑问请在子类中加上@Override
printName(name1);
}
看子类 Drivered中的方法
@Override
public void tellName() {/**由于没有传入参数name是父类的name没有赋值默认为null 所以第一次输出null 不信可以在父类构造器中传入参数name试试看看是不是输出Base 继续看printName**/
System.out.println("Derived tell name:" + name);
}
@Override
public void printName(String name) {/**这里传入了参数name所以默认就是
父类的 name 所以 编译器会去找name的值 开始初始化 所以输出 Base
System.out.println("Derived print name:" + name);
}
下面就是 子类调用自己的构造器 我就不啰嗦了 请多指正!
貌似被你这么一说就更糊涂了,关于String那个,不是同名变量,而是同字符串吧?针对这句话“但字段是不可以重写的.也就说在父类的构造函数中调用tellName()方法时,会用两个name字段同时存在的,jvm也搞不明白也你是调用哪一个了,所以会出现在null。”我的理解略有不同,我觉得是动态分配导致tellName的实际执行是在子类的上下文中,因此输出的是子类上下文哄的name,而此时子类的name还没有被初始化,因而是默认值null。我的问题是这个动态分配是如何实现的,因为以前一直认为多态就是靠obj.function()中的obj来决定到底执行谁,所以这里联想到是不是有一个子类对象的引用在这里起作用,如果是,那么这个引用又是如何传到父类的构造器里的?
代码没有问题,这点请放心,我是自己跑过的,两个类,main方法位于Derived中不会有任何问题的。
这个我知道的哈,其实我经过一晚上的思考,已经确定了是动态分配主导了这一结果,但是以往的经验让我认为这个动态分配是靠对象.方法()的方式在运行时确定的,那就需要一个对象在父类的构造器中起作用,不用质疑肯定是Derived,这点我也调试确认过了,但是我不清楚的是这个子类引用是如何进入到父类构造器中的?
两个方法已经被重写 父类构造器调用 这个两个方法的时候 就是调用的子类的 这两个方法,不知道我这样说 说明白没
这个简单的例子其实考的地方蛮多的.只要好好的理解继承,重写和static的使用就不难判断了.
private String name = "base";
public Base() {
System.out.println("-6-");
tellName();
printName(name);
}
public void tellName() {
System.out.println("-4-");
System.out.println("Base tell name:" + name);
}
public void printName(String name) {
System.out.println("-5-");
System.out.println("Base print name:" + name);
}
}public class Derived extends Base {
private String name = "Derived";
public Derived() {
System.out.println("-3-");
tellName();
printName(name);
}
public void tellName() {
System.out.println("-1-");
System.out.println("Derived tell name:" + name);
}
public void printName(String name) {
System.out.println("-2-");
System.out.println("Derived print name:" + name);
}
public static void main(String[] args) {
Derived derived = new Derived();
}
}
这样就可以看出来是走的顺序了。
结果是:
-6-
-1-
Derived tell name:null
-2-
Derived print name:base
-3-
-1-
Derived tell name:Derived
-2-
Derived print name:Derived至于为什么,真的不能理解
说得很好