2013-03-13 3 views
1

이 개체 (제목에 명시된)는 자식 클래스의 재정의 된 메서드를 호출 할 수 있으므로 다른 자식 메서드 메서드를 호출 할 수없는 이유는 무엇입니까? 메모리 구조, JVM 등의 내부 논리와 같은 가능한 자세한 답변이 필요합니다.자식 클래스 개체에 대한 참조를 가진 부모 클래스 형식 참조 변수가 자식 클래스의 메서드에 액세스 할 수없는 이유

아래 코드는 내 질문에 대한 명확한 이해를 제공합니다.

class A 
{ 
    int x=10; 
    public A() 
    { 
    System.out.println("Constructor of class A called!!!"); 
    } 

    public void sayGreetings() 
    { 
    System.out.println("accept hye from class A"); 
    } 
} 

class C extends A 
{ 
    int x=30;//why this is not accessed by stated object. 
    public C() 
    { 
    System.out.println("Constructor of Class C caled!!!"); 
    } 
    public void sayGreetings() 
    { 
    System.out.println("accept hye from class C"); 
    } 
    public void ssa() 
    { 
    System.out.println("Sat Sri Akal ji from class C"); 
    } 
} 

public class ParentClassTypeObject 
{ 
    public static void main(String[] args) 
    { 
    C cObj=new C(); 
    cObj.sayGreetings(); 
    cObj.ssa(); 
    A aCObj=new C();//this is let say stated object,main object 
    aCObj.sayGreetings();/*here we invoked method will be child class's 
         overriden method.*/ 
    //aCObj.ssa(); //why this line gives error 

    System.out.println("x="+aCObj.x); 
    } 
} 

답변

4

당신이 개체에이인터페이스는 당신이 쓴 때 선택한 하나이기 때문에 : 당신이 aCObj 변수를 통해 C 속성에 대한 액세스를 원하는 경우로 선언

A aCObj = new C(); 

C. 변수는 A, 또는 C을 가리킬 수 있기 때문에

aCObj = new A(); 

그래서, 컴파일러에 의해 정의 된 메소드에 액세스하는 사용자를 제한 : 그것에게 A함으로써

, 당신은 가능한 나중에 쓰기 할 수 있도록 인터페이스는 A 유형으로 공개됩니다.

그 방법은 OOP (다형성)의 주요 포인트 중 하나이기 때문에 여전히 C정의에 액세스 할 수 있습니다.

+0

하지만 내 질문에 왜 오버라이드 된 메서드에 액세스 할 수 있지만 다른 자식 메서드는 액세스 할 수없는 대답을주지 않았다. ineed 대답. 컴파일러가 우리가 aCObj.sayGreetings()를 호출 할 때 자식 클래스에서 재정의 된 메서드를 선택하는 방법. 클래스 A의 메서드 (sayGreetings()가 호출되지 않았습니다.) –

0

은 유형이 A으로 선언되므로 유형 A로 선언 된 메소드에만 액세스 할 수 있습니다. 컴파일러는 또한 타입 C임을 보장 할 수 없다.

예.

또한

public class B extends A { 
    public void sayGreetings() { 
     ... 
    } 
} 

이는 SSA 방법이없는있을 수 있습니다,하지만 여전히

+0

하지만 내 질문에 대한 대답을주지 않은 이유 오버라이드 메소드는 접근 가능하지만 다른 자식 메소드는 접근 할 수 없다. –

+0

예 ... 다시 읽는다. – cowls

+0

하지만 aCObj는 자식 클래스의 메소드에 접근하고있다. (오버라이드 된 코드는 호출시 실행된다.) 자신의 클래스 메소드가 아니라 왜? ? 그것은 자식 클래스의 재정의 된 메서드가 아닌 자체 클래스 메서드라고해야합니다. –

0

목적은 A 형하지 C이다 형식으로 선언 된 객체에 할당 할 수 있도록 당신은 할 수 없습니다 인스턴스 변수에 액세스하십시오. 공개로 설정하면 가능합니다.

0

사례 1. 부모 클래스의 참조 변수가 해당 자식 클래스의 개체를 가리킬 수 있습니다. 사례 2. 자식 클래스의 개체를 가리키는 부모 클래스의 참조 변수를 다음으로 유형 변환 할 수 있습니다. 그 아이 클래스의 객체.

경우 1 : 부모 클래스의 참조 변수는 부모 클래스 내에 정의 된 메서드 만 호출 할 수 있으며 부모 클래스의 메서드를 재정의하는 자식 클래스의 메서드를 호출 할 수도 있습니다. 그러나 메서드를 호출 할 수 없습니다 독점적으로 하위 클래스에만 있습니다.

경우 2 : 상위 클래스의 참조 변수도 하위 클래스의 메소드를 호출 할 수 있습니다.

이것은 다형성의 원리 때문입니다.

1

컴파일러가 IF을 결정하면 참조 변수의 유형에 따라 메소드를 호출 할 수 있습니다. 참조 변수가 클래스 A 인 경우 클래스 A의 메소드 만 호출 할 수 있습니다.

뿐만 아니라 컴파일러는 실제 개체의 유형이 아닌 상속 트리에서 체크를 바닥을 시작하는 참조 변수의 유형에 따라 전화 방법을 결정한다. (이것은 서브 클래스에서 시작하는 모든 길)

그래서이 경우 당신이 aCObj.sayGreetings(); 말할 때 컴파일러는 먼저 A을 .class A는 aCObj의 참조 타입은 실제 개체가 컴파일러 시작 낭포 C 자사의 ok.But 있도록 sayGreetings() 방법을했다 확인 서브 클래스 (C)로부터이 메소드가 슈퍼 클래스 (A)에 구현되고 있는지 어떤지를 조사한다. 메소드 `sayGreetings()은 C 클래스에서 재정의됩니다. 따라서 서브 클래스의 C class sayGreetings() method을 호출합니다. 한편

ssa() 방법은 클래스 C이며 참조 변수가 클래스 A의 때문에 컴파일러는 당신이 시도 할 때 오류를 제공 aCObj.ssa();

그것은 단지 클래스 참조 변수 중 하나 polymorphism.Since이 될 수 있어요 A 또는 C 객체는 컴파일러가 액세스를 수퍼 클래스의 메소드 인 일반적인 메소드에만 제한합니다 .Next는이 메소드가 실제 객체 (C)의 클래스에서 구현되는지 여부를 확인합니다. 슈퍼 클래스 (A)까지의 메소드를 호출하고 슈퍼 클래스의 메소드를 호출합니다. 그러나 구현 된 경우 서브 클래스 (C)의 메소드를 호출합니다.

2

참조 변수 동일한 유형의 객체 또는 동일한 유형의 Sub 세트를 가리 킵니다.

부모와 자녀가 상위 클래스이고 상위가 상위 클래스를 상속하는 두 클래스가 있다고 가정하십시오. 아래 이미지는 자세한 설명을 제공합니다. 당신이 동일한 방법이있는 경우 there.So가 output.And을 줄 것 같이 위의 그림에서 enter image description here

는, 어린이 Object.It의 부모 클래스 개체를 검색 할 상위 클래스 참조 변수는 그것을 발견 할 것이다 자식 클래스 (메서드 재정의) 자식 메서드 재정의 메서드를 실행합니다.

그러나 하위 클래스 참조 변수의 경우 상위 클래스 개체의 하위 클래스 개체를 찾을 수 없습니다. 여기서는 불가능합니다.

enter image description here

희망이 당신의 혼란을 취소합니다.

3

코드를 컴파일하면 컴파일 오류가 발생합니다 (런타임 오류가 아님)./* 컴파일러는 컴파일 동안 aCobj가 타입 A의 기준 인 것을 알고,이 뒤에 이유는

A aCObj=new C(); 

aCObj.sayGreetings()는 점이다. 컴파일러는 aCobj가 A 타입이고 sayGreetings() 메소드가 클래스 A에 있으므로 */

aCObj.ssa();/* 위에서 언급했듯이 컴파일러는 런타임에 대해 전혀 알지 못합니다. 런타임에 aCobj는 클래스 C 유형의 객체를 가리키고 컴파일러를 컴파일하는 동안 aCobj는 클래스 A 유형이고 클래스 A에는 ssa()라는 메소드가 없으므로 컴파일 타임 오류가 발생합니다. */

개체에 대한 간단한 규칙 하나 : 컴파일 타임에 할당 연산자의 왼쪽을 검사합니다. 런타임에 대입 연산자의 오른쪽. 이 문 고려해 동안 컴파일러가 엄격하게 부모 클래스에서 그 방법의 존재를 확인하는 시간을 컴파일하기 때문에

Parent obj =new Child(); obj.method1(); obj.method2();

u는 부모 유형의 OBJ 참조를 사용하여 전화를 걸 무엇이든 방법, 그 방법은 부모 클래스에 제시해야한다 비록 그것이 Child 클래스에 존재할지라도.

관련 문제