Java 정적 결합 및 동적 결합
최근에 나는 Java 지식을 배웠고 Java의 정적 및 동적 바인딩을 배웠습니다. 그런 다음 Baidu에 대한 해당 지식을 요약하고 정리하여 지식 의이 부분을 마스터하는 데 도움이됩니다.
프로그램 바인딩의 개념 :
바인딩은 메소드 호출과 메소드가있는 클래스 (메소드 본문)의 연관성을 나타냅니다. Java의 경우, 결합은 정적 결합 및 동적 결합으로 나뉩니다. 또는 초기 바인딩 및 늦은 바인딩이라고합니다.
정적 바인딩 :
이 메소드는 프로그램이 실행되기 전에 바인딩되며 (즉, 컴파일 프로세스에있는 메소드가 어떤 클래스인지 이미 알고 있음) 컴파일러 또는 기타 연결 프로그램에서 구현됩니다. 예 : C.
Java의 프로그램 편집 기간 동안 단순히 바인딩으로 이해할 수 있습니다. 다음은 Java의 유일한 방법이 사전 바인딩 인 최종, 정적, 개인 및 생성자임을 특히 분명합니다.
동적 바인딩 :
나중에 바인딩 : 런타임시 특정 객체의 유형에 따라 바인딩됩니다.
언어가 늦은 바인딩을 구현하는 경우 작동 중에 물체의 유형을 결정하고 적절한 방법을 별도로 호출하는 메커니즘을 제공해야합니다. 다시 말해, 컴파일러는 여전히 현재 객체 유형을 알지 못하지만 방법 호출 메커니즘은 자체적으로 조사하고 올바른 메소드 본문을 찾을 수 있습니다. 언어마다 늦은 바인딩을 구현하는 방법이 다릅니다. 그러나 우리는 적어도 이런 식으로 생각할 수 있습니다. 모두 객체에 특정 유형의 정보를 설치해야합니다.
동적 바인딩 프로세스 :
최종, 정적, 개인 및 생성자는 조기 바인딩에 대한 이해입니다.
우선 개인 방법의 경우 상속받을 수 없습니다. 상속받을 수 없으므로 서브 클래스의 객체를 통해 호출 할 수있는 방법은 없지만이 클래스 자체의 객체를 통해서만 호출 할 수 있습니다. 따라서 개인 방법은이 방법을 정의하는 클래스에 바인딩된다고 말할 수 있습니다.
최종 방법을 상속받을 수 있지만 덮어 쓰기 (재정의). 하위 클래스 객체를 호출 할 수 있지만, 상위 클래스에 정의 된 최종 방법은 호출됩니다 (이것으로부터 메소드가 최종 유형으로 선언된다는 것을 알 수 있고, 하나는 메소드가 덮어 쓰는 것을 방지하고, 다른 하나는 Java에서 동적 바인딩을 효과적으로 닫는 것입니다).
생성자는 상속받을 수 없습니다 (또한 서브 클래스는 부모 클래스의 매개 변수가없는 생성자를 그들의 생성자로 무조건 상속한다는 말이 있지만, 나는이 진술이 개인적으로 부적절하다고 생각합니다. 우리는 서브 클래스가 상위 클래스의 초기화를 완료하기 위해 부모 클래스의 매개 변수가없는 생성자를 부적절하다고 생각합니다. 부모 클래스의 생성자). 따라서이 생성자가 컴파일 할 때 어떤 클래스에 속한 지 알 수 있습니다.
정적 방법의 특정 원리를 잘 설명 할 수 없습니다. 그러나 온라인 정보와 자체 실험을 바탕으로 정적 메소드는 서브 클래스에 의해 상속 될 수 있지만 서브 클래스에 의해 다시 작성 될 수는 없지만 서브 클래스로 숨겨 질 수 있다고 결론을 내릴 수 있습니다. (이것은 부모 클래스에 정적 메소드가 있고 서브 클래스에 해당 메소드가없는 경우, 아동 클래스 객체 가이 메소드를 호출 할 때 부모 클래스의 메소드가 사용됩니다. 그리고 아동 클래스에서 동일한 방법이 정의되면, 어린이 클래스에서 정의 된 방법이 호수 클래스로 변환되는지, 상관 관계가있는 방법이 정의 된 방법이 정의 될 때, 유일한 차이점이 부모의 대상으로 변환 될 것입니다. 부모 클래스는이 정적 방법에 관계없이, 정적 방법은 숨겨 질 수 있지만 이는 부모 클래스에서 회원 변수를 숨기는 것과 동일합니다.
위에서 우리는 상속 후 메소드를 상속받을 수 없거나 덮어 쓰지 않으면이 방법이 정적 결합을 채택한다는 결론을 내릴 수 있습니다.
Java의 편집 및 작동
Java 컴파일 프로세스는 Java 소스 파일을 Bytecode로 컴파일하는 프로세스입니다 (JVM Executable Code, 즉 .class 파일). 이 과정에서 Java는 메모리를 다루지 않습니다. 이 과정에서 컴파일러는 구문 분석을 수행합니다. 구문이 올바르지 않으면 오류 가보고됩니다.
Java Running Process는 JVM (Java Virtual Machine) Bytecode 파일로드 및 실행 해석을 나타냅니다. 이 과정에서는 메모리 레이아웃의 실제 생성 및 Java 프로그램의 실행입니다.
Java Bytecode를 실행하는 두 가지 방법이 있습니다. (1) 인스턴트 컴파일 방법 : 먼저 바이트를 기계 코드로 컴파일 한 다음 기계 코드를 실행합니다. (2) 설명 실행 방법 : 통역사는 매번 작은 코드를 해석하고 실행하여 Java Bytecode 프로그램의 모든 작업을 완료합니다. (여기서는 Java 프로그램이 실행 프로세스 중에 실제로 두 번의 전환을 거치고, 먼저 바이트 코드로 변환 한 다음 기계 코드로 변환됩니다. 이것이 Java를 한 번의 어디에서나 컴파일하고 실행할 수있는 이유이기도합니다. 다른 플랫폼에서 동일한 바이트 코드를 다른 플랫폼에서 실행하는 것과 같은 해당 Java 가상 머신을 설치할 수 있습니다.
앞에서 언급했듯이, 초기 바인딩 인 최종, 정적, 개인 및 생성자를 제외하고 Java의 방법의 경우, 다른 모든 방법은 동적 바인딩입니다.
전형적인 동적 바인딩은 부모 클래스 및 아동 클래스의 전환 선언에서 발생합니다.
예를 들어 : 부모 p = 새로운 어린이 ();
특정 프로세스 세부 사항은 다음과 같습니다.
1 : 컴파일러는 객체의 선언 유형 및 메소드 이름을 확인합니다.
우리가 xf (args) 메소드를 호출하고 x가 클래스 C의 객체로 선언되었다고 가정하면 컴파일러는 클래스 C에서 f라는 모든 메소드를 나열하고 클래스 C의 슈퍼 클래스에서 상속 된 메소드를 나열합니다.
2 : 다음으로 컴파일러는 메소드 호출에 제공된 매개 변수 유형을 확인합니다.
이름 F가있는 모든 메소드 중 하나의 매개 변수 유형이 호출에 의해 제공된 매개 변수 유형과 일치하면이 메소드가 호출됩니다. 이 프로세스를 "과부하 해상도"라고합니다.
3 : 프로그램이 실행되고 동적 바인딩에 통화 메소드를 사용하면 가상 머신은 x에 의해 가리키는 객체의 실제 유형과 일치하는 메소드 버전을 호출해야합니다.
실제 유형이 d (c의 서브 클래스)라고 가정하고 클래스 d가 f (string)를 정의하면 메소드가 호출되며, 그렇지 않으면 메소드 f (문자열)가 d의 슈퍼 클래스에서 검색됩니다.
Java Virtual Machine이 클래스 메소드 (static method)를 호출하면 객체 참조 유형 (일반적으로 컴파일 시간에 알려짐)에 따라 호출 된 메소드를 선택합니다. 반대로, 가상 머신이 인스턴스 메소드를 호출 할 때 실제 객체 유형 (런타임에만 알려진)에 따라 호출 된 메소드를 선택합니다. 이것은 다형성의 유형 인 동적 결합입니다. 동적 바인딩은 실제 비즈니스 문제를 해결할 수있는 유연성을 제공하며 매우 아름다운 메커니즘입니다.
방법과 달리 Java 클래스에서 멤버 변수 (인스턴스 변수 및 클래스 변수)를 처리 할 때는 런타임 바인딩이 아니라 일반적인 의미에서 정적 바인딩입니다. 따라서 상향 변환의 경우 객체의 메소드는 서브 클래스를 찾을 수 있으며 객체의 속성 (멤버 변수)은 여전히 상위 클래스의 속성 (하위 클래스가 부모 클래스 멤버 변수에서 숨겨져 있음)입니다.
공개 클래스 아버지 {보호 된 문자열 이름 = "아버지 속성"; } 공개 클래스 아들은 아버지를 확장합니다. {보호 된 문자열 이름 = "아들 속성"; public static void main (String [] args) {아버지 sample = new Son (); System.out.println ( "호출 :" + sample.name); }} 결론 : 발신자는 아버지의 속성입니다.
이 결과는 아동 클래스 (부모 클래스의 참조 핸들)의 객체가 상위 클래스 멤버 변수로 호출되었음을 보여줍니다. 따라서 런타임 (동적) 바인딩에 의해 타겟팅 된 범주는 객체의 메소드 일뿐입니다.
이제 서브 클래스 멤버 변수 이름을 호출하려고합니다. 어떻게해야합니까? 가장 쉬운 방법은 멤버 변수를 메소드 getter 양식으로 캡슐화하는 것입니다.
코드는 다음과 같습니다.
공개 클래스 아버지 {보호 된 문자열 이름 = "아버지 속성"; 공개 문자열 getName () {return name; }} 공개 클래스 아들은 아버지를 확장합니다. {보호 된 문자열 이름 = "아들 속성"; 공개 문자열 getName () {return name; } public static void main (String [] args) {아버지 sample = new Son (); System.out.println ( "호출 속성 :" + sample.getName ()); }} 결과 : 아들의 속성이 호출됩니다
Java는 왜 속성에 대한 정적 바인딩 방법을 채택합니까? 정적 바인딩에는 많은 이점이 있기 때문에 런타임 기간이 아닌 컴파일 기간 동안 프로그램에서 오류를 발견 할 수 있기 때문입니다. 이것은 프로그램의 운영 효율성을 향상시킬 것입니다! 방법의 동적 결합은 Java의 주요 특징 인 다형성을 구현하는 것입니다. 다형성은 또한 주요 객체 지향 기술 중 하나이므로 Java는 효율성 비용으로 다형성을 구현하는 것이 가치가 있습니다.
참고 : 위의 컨텐츠의 대부분은 인터넷에서 나오며 작은 부분은 개인적인 의견이며 결코 권위있는 발언입니다. 부적절한 언어 나 잘못된 표현이 있다면 조언을 드리겠습니다.
읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!