2009-10-20 4 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(); 메서드를 호출 할 때 lights_on 메서드를 찾고 bmwCar 개체에서 인스턴스 변수 바퀴 및 표시 등 값을 초기화하는 이유를 알고 싶습니다. 즉 44입니다.JVM은 상속 트리 구조를 어떻게 실행합니까?

lights_on(); 메서드를 Car 클래스에서 실행하면 JVM이 값을 다시 초기화합니까? 참조는 bmwCar.lights_on에서 Car 클래스 lights_on으로 어떻게 전달됩니까? 워크 플로우에 대한 자세한 답변을 찾고 있습니다.

답변

4

당신은 클래스 Vehicle에 멤버 변수를 wheelslights를 선언하고, 당신은 서브 클래스 CarBMWCar에 같은 이름을 가진 멤버 변수를 선언하고 있습니다.

구성원 변수는 이 아니며은 같은 방법으로 재정의됩니다. 하위 클래스 의 멤버 변수는 수퍼 클래스의 변수을 숨 깁니다.

그래서 멤버 변수 집합이 하나도 없습니다. 3 개가 있습니다. 당신은 당신의 방법이 어느 클래스에 속해 있는지에 따라 그 세 가지 중 하나를 보게됩니다. 수퍼 클래스의 멤버 변수는 어떻게 든 다시 초기화되지 않습니다. 그것은 혼란으로, 2. 슈퍼 클래스와 동일한 이름을 가진 멤버 변수를 사용하여

피해야한다 값을 4로, 클래스 Car의 방법 lights_on 내부, 당신은 변수를 볼 수 있습니다 wheels 및 클래스 Carlights , 그리고 그것은 당신이 생각하는 것을하지 않습니다.

+0

@Jesper 답변 해 주셔서 감사합니다 , 상속 구조에서 변수를 재 선언 할 때 JVM이 어떻게 작동하는지 알고 싶습니다. JVM은 lights_on 메서드를 식별하고 Car 클래스에있는 메서드를 어떻게 실행합니까? 컴파일러 자체에 의해 부모 클래스의 참조가 추가됩니다. 어떤 리소스가 있으면 공유 할 수 있습니다. 감사합니다. –

+0

알고 싶은 것을 생각합니다. "다형성"이 무엇입니까. Sun의 Java 자습서 (http://java.sun.com/docs/books/tutorial/java/IandI/polymorphism)에서 살펴보십시오.html – Jesper

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이 어떻게 작동하는지 알고 싶습니다. 컴파일 시간 중에 모호성이 있는지, 또는 멤버를 다시 선언 할 런타임 예외가 있는지 알고 싶습니다. 변수. –

0

처럼 그것을 넣어 재 선언하지 마십시오, JVM은 참조하고 이름, 유형 및 클래스에 의해 현장을 찾습니다. JVM 스펙의 GETFIELD opcode을 참조하십시오.

사실상 JIT 컴파일러 (적어도 핫스팟에서)는 객체 데이터의 지정된 오프셋에서 메모리에 액세스하는 (즉, JIT 컴파일러가 필드 오프셋을 미리 계산하는) 원시 코드로 컴파일합니다. (미안하지만, 이것에 대한 참조가 없지만 JVM의 디버그 버전을 얻으면 어셈블러 코드를 출력하여 그 코드가 무엇인지 알 수 있습니다.)

관련 문제