Java 다형성 물체의 변환 <br /> 여기에 언급 된 객체 유형 변환은 상속 관계가있는 객체가 아니라 모든 유형의 객체가 아닙니다. 상속 관계가없는 객체를 캐스팅 할 때 Java 런타임은 java.lang.classcastException 예외를 던집니다.
상속 체인에서, 우리는 하위 클래스 변환을 부모 클래스 "Upward Transformation"로, 부모 계급 변환을 어린이 클래스 "하향 변환"으로 호출합니다.
여러 번 변수를 부모 클래스의 유형으로 정의하지만이 과정은 상향 변환입니다. 프로그램이 실행되면 동적 바인딩을 사용하여 서브 클래스 방법, 즉 다형성에 대한 호출을 실현합니다.
그러나 때로는 일부 상위 클래스가 가지고 있지 않은 함수를 완성하기 위해서는 상향 변환 된 서브 클래스 객체를 서브 클래스로 변환하고 하향 변환 인 서브 클래스 메소드를 호출해야합니다.
참고 : 상위 클래스의 객체는 서브 클래스 유형으로 직접 캐스트 할 수 없으며 상향 변환 후 서브 클래스 객체는 서브 클래스 유형으로 다시 변환 할 수 있습니다. 다시 말해, 서브 클래스 객체는 아래쪽으로 변환되기 전에 위쪽으로 변환해야합니다. 다음 코드를 참조하십시오.
공개 클래스 데모 {public static void main (string args []) {superclass superobj = sonclass (); 클래스 객체는 직접적으로 // sonclass sonobj2 = (sonclass) superobj = sonclass sonobj1 = (sonclass)} class sonclass {};7 행에서 주석을 제거하면 런타임에 예외가 발생하지만 컴파일은 전달 될 수 있습니다.
아래쪽으로 전환 할 위험이 있으므로, 상위 클래스에 대한 참조를받을 때는 인스턴스를 사용하여 객체가 원하는 하위 클래스인지 확인하십시오.
공개 클래스 데모 {public static void main (string args []) {superclass superclass (); new sonclass (); = (sonclass) superobj} else {system.out.println (superobj); ) SuperObj; 실행 결과 :
① 변환 할 수 없습니다
요약 : 프로그램이 실행될 때 객체의 유형 변환이 확인됩니다.
Java 다형성 및 동적 결합 <br /> Java에서, 부모 클래스의 변수는 부모 클래스의 인스턴스 또는 아동 클래스의 인스턴스를 참조 할 수 있습니다.
먼저 코드를 읽으십시오.
공개 클래스 {public static void main (string [] args) {obj.cry (); .cry ();} class Animal {// 동물의 부름 public void cry () {System.out.println ( "무엇을 콜링 해야할지 모르겠다"); 고양이 공개 공허 cry () {System.out.println ( "Meow ~")} Class Dog Extends Animal {// dog barking public void cry () {System.out.println ( "wow ~"); }} 실행 결과 :
Meow ~ Wool ~를 부르는 방법을 모르겠습니다
위의 코드는 동물, 고양이 및 개 수업의 세 가지 수업을 정의합니다. OBJ 변수에는 유형 동물이 있는데, 이는 동물 계급의 사례뿐만 아니라 고양이와 개 클래스의 사례를 가리킬 수 있습니다. 즉, 부모 클래스의 변수는 부모 클래스의 인스턴스 또는 아동 클래스의 인스턴스를 참조 할 수 있습니다. 모든 고양이는 동물이지만 모든 동물이 고양이는 아니기 때문에 주변의 다른 방법은 잘못입니다.
OBJ는 인간, 고양이 또는 개 일 수 있음을 알 수 있습니다. 다형성은 형태 나 형태가 다른 것을 말합니다.
예를 들어, "인간"에는 여러 가지 표현이나 구현이 있습니다. 운전자, 교사, 의사 등이 될 수 있습니다. , 다음 생에서 교사 또는 의사는 "인간"은 다형성을 가지고 있다고합니다.
다형성이 존재하는 데 필요한 세 가지 조건이 있습니다. 상속, 재 작성 및 부모 변수는 서브 클래스 객체를 나타냅니다.
다형성 방법을 사용하여 메소드를 호출 할 때 :
먼저 메소드가 부모 클래스에 있는지 확인하십시오.
서브 클래스가 메소드를 대체하면 서브 클래스의 메소드가 호출되며, 그렇지 않으면 상위 클래스 메소드가 호출됩니다.
위의 예에서 알 수 있듯이 다형성의 한 가지 장점은 많은 서브 클래스가있을 때 여러 변수를 정의 할 필요가 없다는 것입니다. 다음 예를보십시오.
공개 클래스 데모 {public static void main (String [] args) {// 다형성의 도움으로 많은 동물을 먹일 수 있습니다. Ma.feed (New Fish ()); ) {System.out.println ( "나는 작은 동물입니다. 작은 고양이는 " + f.getfood ());}} 동물을 확장합니다. ; String getfood () {return "bone"}} // mas 실행 결과 :
나는 작은 동물, 물건을 먹고, 나는 작은 고양이, 물고기를 먹고, 나는 개, 뼈를 먹는다
마스터 클래스의 피드 방법에는 두 가지 매개 변수, 즉 동물 유형과 음식 유형이 있기 때문에 아동 클래스의 인스턴스를 전달할 수 있으므로 마스터 클래스는 피드를 위해 여러 가지 방법이 필요하지 않습니다. 다른 동물.
동적 바인딩
다형성의 본질을 이해하기 위해 아래의 Java 호출 방법의 상세한 과정에 대해 이야기 해 봅시다.
1) 컴파일러는 객체의 선언 유형 및 메소드 이름을 확인합니다.
obj.func (param)이 호출되고 OBJ는 고양이 클래스의 대상이라고 가정합니다. func이지만 매개 변수가 다른 여러 메소드가있을 수 있습니다. 예를 들어, 메소드 func (int) 및 func (문자열)가 존재할 수 있습니다. 컴파일러는 CAT 클래스에서 func라는 모든 메소드를 나열하고 Attribute Public에 액세스하고 부모 클래스 동물에서 func에 액세스하는 메소드를 나열합니다.
이러한 방식으로 컴파일러는 호출 할 모든 가능한 후보 방법의 목록을 얻습니다.
2) 다음으로 편집자는 메소드를 호출 할 때 제공된 매개 변수 서명을 확인합니다.
제공된 매개 변수 서명과 정확히 일치하는 모든 메소드에 func라는 메소드가있는 경우이 메소드를 선택하십시오. 이 프로세스를 과부하 해상도라고합니다. 예를 들어, func ( "hello")가 호출되면 컴파일러는 func (int) 대신 func (string)를 선택합니다. 예를 들어 자동 유형 변환이 존재하기 때문에 INT는 메소드 매개 변수와 동일한 서명이없는 경우 검색하기 전에 유형 변환이 수행됩니다 끝 또는 여러 메소드가 일치 한 다음 오류를 컴파일합니다.
이러한 방식으로 컴파일러는 호출 해야하는 메소드 이름 및 매개 변수 서명을 얻습니다.
3) 메소드 수정자가 비공개, 정적, 최종 (정적 및 최종이 나중에 설명 될 것임) 또는 생성자 인 경우 컴파일러는 정적 정적 바인딩을 호출하는 방법을 정확하게 알 수 있습니다 .
이에 따라 호출 된 메소드는 실제 유형의 객체 유형에 따라 달라지며 런타임에서 동적 바인딩을 구현합니다. 예를 들어, func ( "hello")를 호출 할 때 편집기는 동적 바인딩을 사용하여 func (string)를 호출하는 지침을 생성합니다.
4) 프로그램이 실행되고 동적 바인딩을 사용하여 메소드를 호출 할 때, JVM은 OBJ가 참조하는 실제 객체의 실제 유형에 가장 적합한 클래스의 메소드를 반드시 호출합니다. 우리는 OBJ의 실제 유형이 고양이라고 가정했으며, 이는 동물의 서브 클래스 인 고양이이며, func (문자열)가 고양이에서 정의되면 호출됩니다. 그렇지 않으면 동물 계급과 부모 클래스에서 검색됩니다.
이 메소드에 대한 각 호출은 검색이 필요하므로 JVM은 각 클래스에 대한 메소드 테이블 (메소드 Lable)을 생성하여 모든 메소드가 이름을 지정하는 이름, 매개 변수 서명 및 클래스를 나열합니다. 이런 식으로 메소드가 실제로 호출되면 가상 머신은이 테이블 만 찾을 수 있습니다. 위의 예에서 JVM은 CAT 클래스의 메소드 테이블을 검색하여 Call to Func ( "Hello")와 일치하는 메소드를 찾습니다. 이 방법은 cat.func (String) 또는 Animal.Func (String) 일 수 있습니다. super.func ( "hello")이 호출되면 컴파일러는 부모 클래스의 메소드 테이블을 검색합니다.
동물 클래스에 세 가지 메소드가 포함되어 있다고 가정하면 다음은 Cry (), getName () 및 getage ()가 다음과 같습니다.
cry () -> animal.cry ()
getName () -> 동물성 .getName ()
getage () -> 동물성 ()
실제로 동물은 또한 기본 상위 클래스 객체 (나중에 설명 될 예정)를 가지고있어 객체 메소드를 상속받을 수 있으므로 위에 나열된 메소드가 완료되지 않습니다.
CAT 클래스가 동물 클래스에서 Cry () 메소드를 무시하고 새로운 방법 Climbtree ()를 추가한다고 가정하면 매개 변수 목록이 다음과 같습니다.
cry () -> cat.cry ()
getName () -> 동물성 .getName ()
getage () -> 동물성 ()
climbtree () -> cat.climbtree ()
실행할 때 OBJ.cry () 메소드를 호출하는 프로세스는 다음과 같습니다.
JVM은 먼저 동물 클래스의 메소드 테이블 일 수있는 실제 OBJ 유형의 메소드 테이블 또는 CAT 클래스 및 하위 클래스의 메소드 테이블에 액세스합니다.
JVM은 메소드 테이블에서 Method Matching Cry ()를 검색하며, 찾은 후에는 어떤 클래스에 속한 지 알 수 있습니다.
JVM 은이 방법을 호출합니다.