2009-10-20 66 views
1
class Vehicle { 
    public int wheels; 
    public int lights; 
} 

class Car extends Vehicle { 
    public int wheels =4; 
    public int lights =2; 

    public void lights_on(int lights) { 
     //Code to onlights 
    } 
} 

class BMWCar extends Car { 
    public int wheels = 4; 
    public int lights = 4; 
} 

public class TestCar { 
    public static void main(String args[]) { 
     //Creating a new instance of BMWCAR by calling the default 
     // constructor provided by the constructor 

     bmwCar = new BMWCAR(); 
     bmwCar.lights_on(); 
    } 
} 

在上面的例子中,当我运行TestCar.java文件时,JVM的类加载器将TestCar文件加载到方法区域,并执行main方法。当创建一个bmwCar实例时,它会调用BMWCar类的默认构造函数,并执行超级构造函数,即Car类的默认构造函数。我想知道为什么当调用bmwCar.lights_on();方法时,JVM寻找lights_on方法和bmwCar对象,它会初始化实例变量轮子和灯的值,即44JVM如何执行继承树结构?

当在Car类中执行lights_on();方法时,JVM是否重新初始化该值?参考文献如何从bmwCar.lights_on传递到Carlights_on方法?我正在寻找关于工作流程的详细答案。

回答

4

您声明成员变量wheelslightsVehicle类,然后你声明成员变量在子类CarBMWCar相同的名称。

请注意,成员变量是而不是重写类似的方法;您的子类中的成员变量隐藏了超类中的变量。

所以,没有一组成员变量 - 有三个!你会看到其中的一个取决于你的方法在哪个类中。超类的成员变量不会以某种方式重新初始化。里面Car类中的方法lights_on,你会看到变量wheelsCarlights,与2

使用成员变量具有相同的名称如在超应避免值4,因为它是混乱,它并没有做你认为它会做的事情。

+0

@Jesper感谢您的回答,我想知道当我重新声明继承结构中的变量时JVM的行为。 JVM如何识别lights_on方法并执行Car类中的方法,父类的引用是否会由编译器本身添加。如果有的话,可以共享一些资源谢谢 – 2009-10-20 12:22:58

+0

我想你想知道什么是什么“多态性”是。从Sun的Java教程中查看一下:http://java.sun.com/docs/books/tutorial/java/IandI/polymorphism。html – Jesper 2009-10-20 13:13:21

1

不要重新声明成员变量把做这样的

public class Vehicle { 
    public int wheels = -1; 
    public int lights = -1; 
} 

class Car extends Vehicle { 
    { 
    wheels = 4; //set inherited member variable 
    lights = 2; //set inherited member variable 
    } 

    public void lights_on(int lights){ 
    System.out.println("Parameter to lights_on: "+lights); 
    System.out.println("Wheels: "+wheels); 
    System.out.println("Lights: "+this.lights); 
    } 
} 

class BMWCar extends Car { 
    { 
    wheels = 4; 
    lights = 4; 
    } 
} 

public class TestCar { 
    public static void main(String args[]){ 
    //Creating a New Instance of BMWCAR by calling the default Constructor provided by the constructor 
    Car car = new BMWCar(); 
    car.lights_on(1); 
    car = new Car(); 
    car.lights_on(1); 
    } 
} 
+0

@jitter感谢您的回答,我想知道当我重新声明变量时JVM的行为如何,我想知道在编译时本身会有任何歧义,还是会存在运行时异常以重新声明成员变量。 – 2009-10-20 12:19:24

0

从概念上讲,JVM是指由它的名称,类型和类查找领域。请参阅JVM规范中的GETFIELD opcode。实际上,JIT编译器(至少在Hotspot中)编译为本地代码,该代码在对象数据的给定偏移量(即JIT编译器预先计算字段偏移量)时访问内存。 (对不起,我没有这方面的参考,但是如果你得到了JVM的调试版本,你可以让它输出它的汇编代码,看看它是这样做的。)