2015-01-30 1 views
0

나는 모든 기계 객체가 정적 필드 'id'를 사용하여 자동으로 생성 된 코드를 작성한 코드를 작성했습니다. Java에서 다형성을 이해하려고합니다. 예상되는 출력은 1 2 3 4이지만 출력은 1 2 4 6입니다. 왜 이런 현상이 발생했는지 설명 할 수 있습니까? Camera 생성자도 Machine 생성자를 호출하는자바 다형성 동작

class Machine{ 
    static int id=1; 
    private int mach_id; 
    private String name; 
    Machine(){ 
     this.mach_id = id; 
     id++; 
    } 
    public int getId(){ 
     return this.mach_id; 
    } 

} 

class Camera extends Machine { 
    private int mach_id; 
    Camera(){ 
     this.mach_id = id; 
     id++; 
    } 

} 


public class App { 
    public static void main(String[] args){ 
     Machine mach = new Machine(); 
     Camera cam = new Camera(); 
     Machine mach1 = new Camera(); 
     Machine mach2 = new Camera(); 
     System.out.println(mach.getId()); 
     System.out.println(cam.getId()); 
     System.out.println(mach1.getId()); 
     System.out.println(mach2.getId()); 
    } 
} 
+4

Machine 생성자에서 한 번, Camera 생성자에서 한 번씩 두 번씩 ID를 증가시킵니다. 당신의 카메라 클래스는 mach_id 필드를 필요로하지 않는다. 기계는 그 값에 대한 게터를 제공해야한다. 생성자에 System.out.println을 추가하고 워크 플로를 봅니다 ... – MadProgrammer

+0

Ok. 그러나 내가 이해하지 못하는 것은 카메라 오브젝트를 생성 할 때 2 씩 증가하지 않는다는 것입니다. 즉 카메라를 만들었을 때 cam = new Camera()가 하나씩 만 증가했습니다. 그래서 새로운 Camera()를 사용하여 Machine 객체를 만들 때 실제로 Camera 생성자 만 호출합니다. 그래서이 경우 왜 2 씩 증가합니까? 나는 순진이라고 들릴지도 모르지만 나는 OOPs에 익숙하지 않으므로 나를 참아주십시오. 감사합니다. –

답변

4

이 일어나는 것이다. id은 현재 1입니다. 따라서 새 객체에 mach_id1이고, id이 증가합니다.

Camera cam = new Camera(); 

Camera 생성자를 직접 호출합니다.

모든 생성자가 수행하는 첫 번째 작업은 수퍼 클래스의 생성자를 호출하는 것입니다. 명시 적으로 그렇게하지 않았다면 암묵적으로 수퍼 클래스의 인수가없는 생성자를 호출합니다. 이제 Machine 생성자가 호출됩니다.

는이 오브젝트의 mach_id의 값을 설정

(이것은 다음 id 증가 2이다 id의 현재 값에 Machine으로 보는.

을 이제 Camera 생성자가 자신의 작업을 시작한다.이 얻어 현재 3입니다 id의 현재 값은 mach_id에 넣 및 id을 증가시킨다. 그것은 지금 4입니다.

을 지금 여기에 까다로운 부분이다. Cameramach_id입니다 mach_idMachine에 숨 깁니다. 그러나 getID()Machine에는 Camera에 정의 된 mach_id이 표시되지 않습니다. 그 중 하나는 Machine에 있습니다. 그래서 그것을 호출하면 supeclass 생성자에 대한 호출에서 값 2를 얻습니다. Camera에서 만든 비공개 필드를 볼 수없고 그 값에 대한 지식이 없습니다 (3).

그리고 새로운 Camera 개체를 다시 생성합니다. 변수를 Machine 개의 변수에 넣었으나 위에서 언급 한 사실은 변경되지 않습니다. 호출하는 메서드는 여전히 수퍼 클래스 메서드에서 호출됩니다.

+0

최고. 이것은 그것을 설명합니다. –

1

참고. 따라서 Camera 개체를 만들 때마다 id이 2 씩 증가합니다 (한 번 Machine(), 그 다음에 Camera()). 어쩌면 MachineCamera 생성자에 출력을 추가하면 이해하기가 쉽습니다.

Camera() { 
    // the Machine() constructor will be called and executed HERE 
    this.mach_id = id; 
    id++; 
} 
+0

좋습니다. 그러나 내가 이해하지 못하는 것은 카메라 오브젝트를 생성 할 때 2 씩 증가하지 않는다는 것입니다. 즉 카메라를 만들었을 때 cam = new Camera()가 하나씩 만 증가했습니다. 그래서 새로운 Camera()를 사용하여 Machine 객체를 만들 때 실제로 Camera 생성자 만 호출합니다. 그래서이 경우 왜 2 씩 증가합니까? 나는 순진이라고 들릴지도 모르지만 나는 OOPs에 익숙하지 않으므로 나를 참아주십시오. 감사합니다 - Ishan Bhatt –

+0

@IshanBhatt 대답에서 설명 할게 – sprinter

+0

생성하는 개체는 호출하는 생성자 (즉, = 연산자의 오른쪽)에 따라 다릅니다. 'Camera()'생성자를 호출하면 항상'Camera' 객체를 생성합니다. = 연산자의 왼쪽은 객체를 저장하는 유일한 방법입니다. 따라서'Machine machine = new Camera()'를 사용하면'Camera' 객체를 생성하지만 분명히 'Machine'으로 저장합니다. –

2

나는 그것을 가치가 OO 측면에서이 생각뿐 아니라 생성자의 역학으로 생각 -이 당신이 장기적으로 더 많은 코딩 도움이 될 것입니다.

extends 관계에 대한 간단한 생각은 as is-a입니다. 다시 말해 코드에 CameraMachine 인 것입니다. 따라서 Machine에 해당하는 사항은 Camera에 해당하며 언제든지 Machine이 필요하면 언제든지 Camera을 사용할 수 있습니다.

귀하의 경우에 Machine 번을 id 씩 증가 시켰다고 말씀하셨습니다. 그리고 이라고 말했을뿐만 아니라 Machine이기 때문에 Machine이 수행하는 모든 작업을 수행하면 id이 증가합니다. 당연히 이것은 두 번의 증분을 의미합니다. 한 번은 Machine으로, 한 번은 Camera으로 증가합니다.

두 생성자가 모두 ID를 설정 한 다음 증가합니다. main 메서드는 기계와 카메라 3 개를 만듭니다. 그래서 ID가 될 것이다

기기 ID = +1 1, ID = 2 카메라 ID = +2 2, ID = 4 카메라 ID = +2 4, 식 6 카메라 ID = 6

는 따라서 출력 1, 2, 4, 6

+0

예. 알겠습니다. 하지만 카메라 객체를 만들 때 카메라 캠 = new Camera()가 2 씩 증가하지 않습니다. –

+0

예. 그것은 자신의 id를 설정 한 후에 2 * 증가합니다. 다음 Camera 객체는 이전 객체보다 큰 id 2를가집니다. – sprinter

+0

@IshanBhatt는 이것에 대해 완벽하게 알기 쉽습니다 : 새로운'Camera'가'Machine' 또는'Camera' 변수에 할당되는지 여부는 생성자의 동작에 * no * 차이를 만듭니다. – sprinter

0

로빈 그렇지 polymorphism

자바에서 모든 약 inheritance 개념이다 말했듯이, 인수없이 기본 클래스의 생성자가 자동으로 DERI에서 호출되는 ved 클래스 생성자. Human 클래스는 walk 방법

있다

경우, 의미 많이하고 당신은 Human의 생성자가 객체 s 캔트 호출 후 호출되지 않은 경우 Human에서 상속 클래스 Student s = new Student()

에서 인스턴스를 확인하는 메모리에서 초기화되지 않은 메서드 워크

그래서 슈퍼 생성자가 앞서 파생 클래스 생성자를 호출했습니다.

Machine mach = new Machine(); 

Machine 생성자를 직접 호출됩니다 여기