2017-02-27 4 views
-3

업 캐스팅/다운 캐스팅 및 정적 바인딩 및 동적 bidning의 경우 이러한 경우에 이해하는 데 어려움이 있습니다. 다음과 같은 클래스 및 인터페이스 예를 고려해보십시오 :Java 업 캐스팅/다운 캐스팅 및 상속 사기에 대한 질문

public class Marsupial { private String name; 
     Marsupial(String name) {  
     this.name = name;  
     } 
     void eats() { 
     System.out.println("Eats #1"); 
     } 
     String getName(){ return name;  
     } 
     } 


    abstract class Herbivore extends Marsupial { 
     Herbivore(String name) { 
     super(name);  
     } 
     void eats() { 
     System.out.println("Eats #2");  
     } 
     abstract void chews(boolean b); 
     } 


    interface Australian { 
    public void greets(Koala k); 
    } 


    public class Koala extends Herbivore implements Australian { 
     Koala(String name) { 
     super(name); 
     } 
     public void greets(Koala k) { 
     System.out.println("G'day mate!"); 
     System.out.println(getName() + " " + k.getName()); 
     } 
     void chews(boolean b) { 

     System.out.println("Yum yum!"); 
     } 
     void chews(int i) { System.out.println("Delicious!");  
     } 
     void likes(Koala k) { 
     greets(k); 
     k.greets(this); }  
     } 

을 지금은 드라이버 클래스가 좀 이상한 일이 내가 왜 확실하지 오전 일어나고 알의 모든 클래스를 사용할 수 있도록합니다. 예를 들어

,

public class Driver { 
    public static void main(String[] args) { 
    Marsupial m = new Marsupial("Kate"); 
    Marsupial m2 = new Koala("Kim"); 
    System.out.println(m.getClass() == m2.getClass()); 
       }  
} 

이 거짓으로 판명. 그들은 같은 클래스가 아닙니다. 여기 정확히 무슨 일이 일어나고 있는지. 우리는 왼쪽에 유대류가 있고 오른쪽에 다른 것이 있습니다. 그렇다면 우리가 메서드를 호출 할 때 중요한 것은 유일한 것입니까? 컴파일러가 실행되고 메소드를 살펴볼 때 equals 연산자의 오른쪽을 확인하고 ok라고 말하면 클래스와 같은 클래스이므로 클래스를 사용할 클래스를 결정할 때 오른쪽에 정의 된 클래스의 메소드를 사용하십시오. 내가 쓴 주요 메서드 내 경우에도

,

:

Marsupial m = new Koala("jack"); 
m.eats(); 

이 밖으로 인쇄는 먹는다 # 2. 코알라에는 먹는 방법이 없기 때문에 체인의 위쪽으로 한 수준 올라간다. 그래서 다음 단계는 Herbivore가 될 것이고, 그게 먹는() 메서드를 가지고 있기 때문에 거기에있는 아이디어 일 것이다. ?

주요 방법의 또 다른 예 :

Herbivore h = new Koala("June"); 
((Marsupial)h).eats(); 
다음

저를 던지는 것은 초식 따라서 instaniated 할 수없는 추상 클래스는 여기처럼 우리가 실제 객체에 대한 참조로 추상 클래스를 사용할 수 있다는 것입니다 객체를 인스턴스화하는 클래스에 할당 할 수 있습니다. 하지만 가장 혼란 스러울 이유는 우리가 Koala 클래스에 있고 우리는 eats() 메서드를 호출하지만 변수를 Marsupial로 UPCAST합니다. 그래서 자동적으로 우리를 Marsupial 클래스에 넣습니다. 그러므로 다른 클래스의 Marsupial 클래스 메소드가 Marsupial에 타입 변환 된 이후에 호출 되었기 때문에 메소드를 호출 할 때마다 메소드를 호출합니다. 따라서 그것의 Eats # 1을 호출합니다. 인터페이스가 서브 클래스의 인스턴스에 할당 보는 werid 것

Australian a = new Koala("Khloe"); 
a.chews(true); 

: 우리가 주에서이 작업을 수행하는 경우

혼란의 또 다른 영역입니다. 그것은 뻔한 것 (사실)으로 불리는 것을 혼란스럽게합니다. 그래서 코알라 객체로 정의 되었기 때문에 우리는 코알라 클래스에 속해 있으며 코알라 메소드가 존재한다면 그것을 사용해야하고 그렇지 않다면 한 레벨 위로 올라가서 그 메소드가 있는지 확인합니다. 그러나 여기 방법은 유효하지 않습니다. 오스트레일리아에서 프로토 타입 방법이 있고 코알라가 정의한 경우에만 작동합니까? 그러면 작동할까요? 이것이 인터페이스를 하위 클래스의 객체로 설정하려는 생각입니까? 코알라는 오스트레일리아 사람이하지 않기 때문에 그 방법이 있지만, 작동하지 않을 것입니다.

그리고 우리는 주와 같은의 코드가있는 경우 : 초식가 정의되지 않은 메서드를 프로토 타입과 코알라를 정의한했다 때문

Herbivore h = new Koala("Stacy"); 
h.chews(true); 

이 "냠 냠"인쇄됩니다. 그러나 Herbivore가 프로토 타입 방법을 사용하지 않으면 작동하지 않습니다.

이 메인에서 실행된다면 내가 가진 마지막 질문은 : 이것은 코알라가이 방법을 가지고 있다는 사실에도 불구하고 있기 때문에 작동하지 않습니다

Herbivore h = new Koala("Kali"); 
h.chews(4); 

, 그것은 초식에 정의되지 않은, 그래서 그것은 잘못이다 .

당신이 제공 할 수있는 모든 정보 또는 정보가 도움이 될 수 있도록 도와주세요.

는 모든 답은 하나입니다 당신에게

+4

여기에 질문 수가 줄어 듭니다. 그러나 그들 모두는 왜 당신이 그것을 시도하고 다양성을 보지 않는지를 보았습니다. 이 질문을 구성하는 것보다 시간이 적게 걸렸을 것입니다. –

답변

0

감사합니다 멀리 JVM에 관한 로 한 조금 변수 유형에 대해하지 치료를하지,하지만 실제 타입합니다 ( 하나 new 키워드와 함께 사용) . 변수 유형은 컴파일러에 대해서만 가능하므로 안전을 보장하기 위해 개발 초기에 이 가능합니다.

+0

이것에 대한 일반적인 관점은 변수는 선언 된 타입을 가지며 객체는 런타임 타입을가집니다. 선언 된 유형은 인스턴스에서 호출 할 수있는 메소드를 알려줍니다. 하위 유형에 메소드가 있지만 선언 된 유형이 없으면 호출 할 수 없습니다. 런타임 유형은 실제로 실행되는 인스턴스 메소드의 버전을 결정합니다. 런타임 유형에서 오버라이드 (override)됩니다 (있는 경우). –