JavaRush /Java Blog /Random-KO /참조 유형의 확장 및 축소

참조 유형의 확장 및 축소

Random-KO 그룹에 게시되었습니다
안녕하세요! 이전 강의 중 하나에서 기본 유형 캐스팅에 대해 논의했습니다. 우리가 무슨 말을 했는지 간단히 기억해 봅시다. 참조 유형의 확장 및 축소 - 1우리는 기본 유형(이 경우 숫자)을 차지하는 메모리 양에 따라 중첩 인형으로 표현했습니다. 기억하는 것처럼 작은 중첩 인형을 더 큰 인형에 배치하는 것은 실제 생활과 Java 프로그래밍 모두에서 간단합니다.
public class Main {
   public static void main(String[] args) {
        short smallNumber = 100;
        int bigNumber =  smallNumber;
        System.out.println(bigNumber);
   }
}
이것은 자동 변환 또는 확장 의 예입니다 . 이는 자체적으로 발생하므로 추가 코드를 작성할 필요가 없습니다. 결국, 우리는 특별한 일을 하지 않습니다. 우리는 단지 더 작은 중첩 인형을 더 큰 중첩 인형에 넣는 것뿐입니다. 반대로 큰 마트료시카 인형을 작은 인형에 넣는 것은 또 다른 문제입니다. 이것은 인생에서는 할 수 없지만 프로그래밍에서는 가능합니다. 그러나 한 가지주의 사항이 있습니다. int변수에 값을 넣으려고 하면 short쉽게 작동하지 않습니다. 결국 16비트의 정보만 변수에 들어갈 수 short있지만 값은 int32비트를 사용합니다! 결과적으로 전송된 값이 왜곡됩니다. 컴파일러는 우리에게 오류를 표시할 것입니다(“ 친구, 당신은 의심스러운 일을 하고 있습니다! ”). 그러나 우리가 값을 캐스팅할 유형을 명시적으로 지정하면 여전히 그러한 작업을 수행합니다.
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       bigNumber = (short) bigNumber;

       System.out.println(bigNumber);

   }

}
위의 예에서는 그렇게 했습니다. 연산은 완료되었으나 short32비트 중 16비트만 변수에 들어가므로 최종 값이 왜곡되어 결과적으로 -27008 이라는 숫자를 받게 되었습니다 . 이 작업을 명시적 변환 또는 축소 라고 합니다 .

참조 유형의 확장 및 축소의 예

이제 동일한 작업에 대해 이야기하지만 기본 유형이 아닌 객체 및 참조 변수 에 적용 가능합니다 ! Java에서는 이것이 어떻게 작동합니까? 실제로는 매우 간단합니다. 서로 관련이 없는 개체가 있습니다. 명시적으로나 자동으로 서로 변환될 수 없다고 가정하는 것이 논리적입니다.
public class Cat {
}

public class Dog {
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Dog();//error!

   }

}
물론 여기서는 오류가 발생합니다. 클래스는 서로 관련이 Cat없으며 Dog서로 "변환기"를 작성하지 않았습니다. 우리가 이것을 할 수 없다는 것은 논리적입니다. 컴파일러는 이러한 객체를 서로 변환하는 방법을 모릅니다. 물체가 서로 연결되어 있는지는 또 다른 문제입니다! 어떻게? 우선, 상속을 사용합니다. 상속을 통해 소규모 클래스 시스템을 만들어 보겠습니다. 동물을 대표하는 일반 클래스가 있습니다:
public class Animal {

   public void introduce() {

       System.out.println("i'm Animal");
   }
}
아시다시피 동물은 가축이고 야생입니다.
public class WildAnimal extends Animal {

   public void introduce() {

       System.out.println("i'm WildAnimal");
   }
}

public class Pet extends Animal {

   public void introduce() {

       System.out.println("i'm Pet");
   }
}
예를 들어 개(집개와 코요테)를 생각해 봅시다.
public class Dog extends Pet {

   public void introduce() {

       System.out.println("i'm Dog");
   }
}





public class Coyote extends WildAnimal {

   public void introduce() {

       System.out.println("i'm Coyote");
   }
}
우리 클래스는 인식하기 쉽도록 의도적으로 가장 원시적입니다. 여기서는 필드가 실제로 필요하지 않으며 한 가지 방법으로 충분합니다. 다음 코드를 실행해 보겠습니다.
public class Main {

   public static void main(String[] args) {

       Animal animal = new Pet();
       animal.introduce();
   }
}
콘솔에 무엇이 출력될 것이라고 생각하시나요? introduce클래스 Pet또는 클래스 메소드가 작동 합니까 Animal? 계속 읽기 전에 답변의 타당성을 입증해 보십시오. 결과는 다음과 같습니다! 저는 Pet입니다. 답변이 왜 이렇게 나왔나요? 간단 해. 부모 변수와 자식 개체가 있습니다. 작성:
Animal animal = new Pet();
참조 유형을 확장Pet 하고 해당 객체를 변수에 저장 했습니다 Animal. 기본 유형과 마찬가지로 Java의 참조 유형 확장은 자동으로 수행됩니다. 이를 위해 추가 코드를 작성할 필요가 없습니다. 이제 상위 참조에 하위 개체가 연결되어 있으며 결과적으로 해당 메서드가 하위 클래스에서 호출되는 것을 볼 수 있습니다. 이 코드가 작동하는 이유를 여전히 완전히 이해하지 못한다면 간단한 언어로 다시 작성하세요.
Животное животное = new ДомашнееЖивотное();
그건 문제가 되지 않죠? 이것이 실제 생활이라고 상상해 보세요. 이 경우 링크는 "동물"이라고 적힌 간단한 종이 태그입니다. 그런 종이를 가져다가 애완 동물의 목걸이에 붙이면 모든 것이 잘 될 것입니다. 모든 애완동물은 여전히 ​​동물입니다! 반대 프로세스, 즉 상속 트리에서 상속인으로 이동하는 과정은 범위를 좁히는 과정입니다.
public class Main {

   public static void main(String[] args) {

       WildAnimal wildAnimal = new Coyote();

       Coyote coyote = (Coyote) wildAnimal;

       coyote.introduce();
   }
}
보시다시피 여기서는 개체를 캐스팅하려는 클래스를 명시적으로 나타냅니다. 이전에는 변수가 있었고 WildAnimal지금은 Coyote상속 트리 아래로 이동합니다. 컴파일러가 명시적인 표시 없이 이러한 작업을 건너뛰지 않는 것이 논리적이지만 괄호 안에 유형을 지정하면 모든 것이 작동합니다. 참조 유형의 확장 및 축소 - 2 좀 더 흥미로운 또 다른 예를 살펴보겠습니다.
public class Main {

   public static void main(String[] args) {

       Pet pet = new Animal();//error!
   }
}
컴파일러에서 오류가 발생했습니다! 이유는 무엇입니까? 사실은 상위 개체를 하위 변수에 할당하려고 한다는 것입니다. 즉, 다음을 수행하고 싶습니다.
ДомашнееЖивотное домашнееЖивотное = new Животное();
하지만 캐스팅하려는 유형을 명시적으로 지정하면 성공할 수 있을까요? 숫자가 맞는 것 같습니다. 시도해 보겠습니다! :)
public class Main {

   public static void main(String[] args) {

       Pet pet = (Pet) new Animal();
   }
}
스레드 "main" java.lang.ClassCastException의 예외: 동물을 Pet 오류로 캐스팅할 수 없습니다! 이번에는 컴파일러가 불평하지 않았지만 그 결과 예외가 발생했습니다. 우리는 이미 그 이유를 알고 있습니다. 즉, 상위 개체를 하위 변수에 할당하려고 합니다. 사실, 왜 이것이 불가능합니까? 모든 동물이 애완동물은 아니기 때문입니다. 개체를 생성 Animal하고 이를 변수에 할당하려고 합니다 Pet. 그러나 예를 들어, 코요테도 가축이지만 가축은 Animal아닙니다 . Pet즉, 다음과 같이 작성할 때:
Pet pet = (Pet) new Animal();
new Animal()어떤 동물이든 거기에 있을 수 있으며, 가축일 필요는 없습니다! 당연히 귀하의 변수는 Pet pet애완동물(및 그 후손)을 저장하는 데에만 적합하며 모든 사람에게 적합하지는 않습니다. 따라서 이러한 경우 Java에서 특수 예외가 생성되었습니다. 즉, ClassCastException클래스를 캐스팅할 때 발생하는 오류입니다. 더 명확하게 하기 위해 다시 말해보자. 상위 변수(참조)는 하위 클래스의 객체를 가리킬 수 있습니다.
public class Main {

   public static void main(String[] args) {

       Pet pet =  new Pet();
       Animal animal = pet;

       Pet pet2 = (Pet) animal;
       pet2.introduce();
   }
}
예를 들어 여기서는 아무런 문제가 없습니다. Petlink 로 가리키는 객체가 있습니다 Pet. 그런 다음 새 링크가 동일한 개체를 가리키기 시작했습니다 Animal. animal그 후에 우리는 로 변환을 수행합니다 Pet. 그런데 우리는 왜 이런 짓을 한 걸까요? 지난번에는 예외가 있었습니다! 이번에는 원래 개체가 Pet pet!
Pet pet =  new Pet();
이전 예에서는 객체였습니다 Animal.
Pet pet = (Pet) new Animal();
하위 변수에는 상위 개체를 할당할 수 없습니다. 반대로, 당신은 그것을 할 수 있습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION