2017-11-23 3 views
5

정적 바인딩동적 바인딩에 대한 기사를 읽었습니다. 그리고 다음과 같은 질문 (내가 많이 검색 아직 그것에 대해 어떤 언급을 찾을 수없는 것)가 :Java에서 정적 바인딩 및 동적 바인딩 문제

예를 들어, 나는 다음 코드 줄이 있습니다

Person a = new Student(); // Student is a subclass of Person 
a.speak(); 

우리가 '무엇을 이미 알고있는 컴파일 시간은 이고 컴파일러는 speak()에 대한 메서드 정의가 Person에 존재하는지 확인하고 존재하는 경우 호출합니다. 그리고 런타임에, 그것은 직접 전화하지 않는 이유

그래서 내 질문은 (이 경우 실제 개체가 명확하게 Student입니다) a 가리키는되는 실제 개체의 speak() 메소드를 호출 speak() 클래스 Student의 컴파일 시간은이지만 실행하려면 런타임까지 기다려야합니까? 이것의 뒤에 어떤 이유가 있습니까?

+0

소프트웨어를 컴파일하는 것이 실행하는 것과 다릅니다. –

+0

* 컴파일러에게'a'는'Student'보다는'Person'으로 취급되어야한다고했기 때문에. 왜 요청한 것과 다른 방식으로 코드를 컴파일해야합니까? 그 다른 전략에 대해 어떤 이점이 있다고 생각합니까? – Holger

답변

3

코드가 컴파일 될 때 어떤 메소드를 호출해야하는지 명확하지 않은 경우가 있습니다. 런타임에만 확인할 수 있습니다.

간단한 코드를 예로 들어 보겠습니다.

class Animal{ 

    public void makeNoise(){ 
     System.out.println("Default"); 
    }; 
} 

class Dog extends Animal{ 

    //override the makeNoise() 
    public void makeNoise(){ 
     System.out.println("Woof"); 
    }; 
} 

class Cat extends Animal{ 

     //override the makeNoise() 
     public void makeNoise(){ 
      System.out.println("Meow"); 
     }; 
    } 

public class Sounds{ 

    public static void AnimalSounds(Animal animal){ 
    animal.makeNoise(); 
    } 

    public static void main(String args[]){ 

     Animal dog = new Dog();  
     Animal cat = new Cat(); 
     AnimalSounds(dog); 
     AnimalSounds(cat); 
    } 
} 

AnimalSounds(Animal animal) 방법은 동물 ISA 테스트를 통과하고 그 객체의 각각의 메소드를 호출 개체 걸린다. 보시다시피, 다른 유형의 객체에서 동일한 메소드를 사용할 수 있으므로 코드 중복도 제거됩니다.

호프는이 문제를 해결하기 위해 노력하고 있습니다.

+0

먼저 감사드립니다. 하지만 위의 예에서 "때로는 어떤 메소드를 호출해야하는지 명확하지 않다"에 대한 세부 정보를 제공 할 수 있습니까? – DunDev

+0

animal.makeNoise(); 여기, 컴파일 타임에 그것은 객체의 타입을 알지 못한다. 런타임에 특정 동물 객체를 전달하고이를 기반으로 해당 동물의 각 메소드를 호출합니다 (예 : Dog 또는 Cat) –

3

이 항목을 이해하려면 일반적으로 컴파일 및 런타임 프로세스가 무엇인지 알아야합니다. 즉, 앱 컴파일러를 빌드 할 때 모든 코드를 검토하여 일관성, 안전성 및 실행 가능성을 확인하십시오. 컴파일러가 발견 한 오류가 없다면 소스 코드 (java 개)에서 class 개의 파일을 생성합니다. 앱이 실행 중일 때 파일이 메모리에로드되고 JVM이 명령으로 app 명령을 실행한다는 의미입니다. 귀하의 예제에서

:

Person a = new Student(); // Student is a subclass of Person 
a.speak();  

컴파일 과정 : 컴파일러 확인이 라인 : 형 안전 (호환성)에 대한 Person a = new Student();. 따라서 학생 is a 컴파일이 다음 행으로 넘어 가면 실패합니다. 다음 줄에서 : a.speak(); 컴파일러는 a 유형을보고, Person이고 speak() 방법을 Person 유형으로 찾습니다. 해당 메소드가 컴파일러에 의해 설정되지 않으면 컴파일 프로세스가 실패합니다.

런타임 프로세스 : JVM이 실행되면 라인 : 저면 (자식 클래스)에 상위 (상위 클래스)에서 초기화 프로세스를 통해가는 Person a = new Student();한다.다음 라인에서 : a.speak(); JVM 발견 student 참조를 통해 객체 aStudent에있는 경우 speak() 메소드를 찾은 다음 실행합니다. 그렇지 않으면 부모 클래스 Person에서 speak() 메소드를 실행합니다. 상속 대상에서

또 다른 예 :

class Person { 
    public void speak() {} 
    public void think() {} 
} 

class Student extends Person { 
    @Override 
    public void speak() {} 
    public void speakALot() {} 
} 

Person a = new Student(); 
a.speak(); // calling overrided version of speak() 
a.think(); // since this method is not overrided in child class it will be called from parent class 
a.speakALot(); // since Person doesn't know anything about specific methods of derived classes compilation fails 

Student b = new Student(); 
b.speak(); // calling speak() method of student object 
b.think(); // inheritance trick, child class keeps reference to its base class and that's why public and protected fields and methods are available 
b.speakALot(); // calling speakALot() method of student object 
+0

감사합니다. 훌륭한 설명을 제공합니다 ..하지만 질문이 있습니다. javatpoint turorials에서 java를 공부하고 있습니다.이 링크 [정적 바인딩 및 동적 바인딩] (https://www.javatpoint.com/static-binding-and-dynamic-binding) 바인딩이 메서드 호출을 메서드 본문에 연결하지만 일부 사례를 이해하는 데 문제가 있습니다. 예를 들어 각 메서드 호출에 바인딩 형식을 추가하기 위해 답을 편집 할 수 있습니까? 또는 여기에 적어도됩니다. –

+1

[튜토리얼] (http://javaconceptoftheday.com/static-binding-and-dynamic-binding-in-java/)을 먼저보십시오. 만약 당신이 질문을 가지고 내 대답을 업데이 트됩니다 – jibrahim

+0

나는이 문제가 내가 옳은지 이해하지 못했는지를 결정할 것이라고 믿는다. 정적 및 동적 바인딩은 단계 (옵션이 아님)를 의미하며, 둘 다 일어날 수있다. 메서드 본문을 결정하는 동일한 메서드 호출을 호출해야합니까 ?? –

0

난 그냥 으로는 다음과 차량의 종류를 테스트 할 수있는 범용 클래스를 작성합니다.

public class Workshop{ 
    public boolean test(Vehicle vehicle){ 
     vehicle.start(); 
     vehicle.stop(); 
     //...more code 
     return true; 
    } 
} 

Vehicle의 하위 클래스가 작성되지 않았지만이 코드는 Vehicle 유형으로 만 컴파일 할 수 있습니다. 일반적으로 프레임 워크는 구체적인 유형이없는 일반 유형을 기반으로 처리를 제공하는이 기능을 이용합니다 (클라이언트는 하위 클래스 계층을 자유롭게 확장 할 수 있습니다). 이 경우 컴파일러는 차량에 최소한 하나의 구현이 있는지 확인합니다 ({}와 같은 null 구현도 허용됨) 코드를 위반하지 않도록 사용할 수 있습니다.