JavaRush /Java Blog /Random-KO /Java에서 참조 유형 변환
Sant9Iga
레벨 41

Java에서 참조 유형 변환

Random-KO 그룹에 게시되었습니다
좋은 하루 되세요, 자바라쉬 사람. Java에서 참조 유형 캐스팅에 대한 질문을 받기 시작했습니다. 매번 같은 내용을 반복하지 않기 위해 짧은 글을 쓰기로 결정했습니다.

먼저 타입 캐스팅이 무엇인지 살펴보겠습니다.

유형 캐스팅(유형 변환)은 한 유형의 변수 값을 다른 유형의 값으로 변환하는 것입니다. 그것이 무엇인지, 무엇과 함께 먹는지에 대한 예를 살펴 보겠습니다. 몇 가지 클래스 계층 구조가 있습니다( 그림 1 참조 ). 여기에서 계층 구조의 모든 클래스, 누가 누구를 상속하는지, 각 클래스의 메서드를 볼 수 있습니다. 그림 1확장 및 축소 내전이 있습니다. 우리는 클래스 Cat가 클래스의 자손임을 알 수 있습니다 Pet. Pet는 클래스의 후계자입니다 Animal. 우리가 쓸 때 :
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
이는 확장 형변환 (또는 암시적 형변환)입니다. 우리는 링크를 확장 animalCat했습니다 animalDog. Cat그들은 객체 와 를 참조합니다 Dog. 이러한 캐스트를 사용하면 에는 있지만 에는 없는 animalCat/animalDog링크를 통해 메서드를 호출 할 수 없습니다 . 축소 (또는 명시적) 캐스트는 반대 방향으로 발생합니다. Cat/DogAnimal
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
우리는 이 객체를 어떤 유형으로 캐스팅할지 명확하게 표시했습니다. 하지만 조심하세요!!! 다음과 같이 하면:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
컴파일러는 이 코드를 건너뜁니다. 그러나 RunTime그것은 당신에게 던져질 것입니다:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTimeCat두 가지 다른 클래스가 있음 을 알 수 있습니다 YorkshireTerrier. 축소 변환 중에 ClassCastException을 방지하려면 instanceof.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
    YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
이면 할당이 발생하고, 그렇지 않으면 아무 일도 일어나지 않습니다 animalCat.YorkshireTerrier

이제 메소드를 잃어버리고 그러한 오류가 발생할 수 있는 경우 이것이 왜 필요한가요?

그림 1 의 다이어그램에 따라 제가 만든 코드를 살펴보겠습니다 . 1 . 수업Animal
public abstract class Animal
{
    String name;
    int age;
    String nameOfClass = getClass().getSimpleName();
    public void eat(){
        System.out.println(nameOfClass + ": Omnomnom");
    }
    public void sleep(){
        System.out.println(nameOfClass + ": Z-z-z-z");
    }
}
WildAnimal상속받은 클래스Animal
public abstract class WildAnimal extends Animal
{
    public void steelChicken()
    {
        System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
    }
}
Pet상속받은 클래스Animal
public abstract class Pet extends Animal
{
    public void peeInTray(){
        System.out.println(nameOfClass + ": Master, I peed");
    }
}
Fox상속받은 클래스WildAnimal
public class Fox extends WildAnimal
{
    public void eatColobok(){
        System.out.println(nameOfClass + ": I will eat you, Colobok");
    }
}
Wolf상속받은 클래스WildAnimal
public class Wolf extends WildAnimal
{
    public void hawlAtTheMoon(){
        System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
    }
}
Cat상속받은 클래스Pet
public class Cat extends Pet
{
    public void sleepOnKeyboard(){
        System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
    }
}
YorkshireTerrier상속받은 클래스Pet
public class YorkshireTerrier extends Pet
{
    public void bark(){
        System.out.println(nameOfClass + ": Meow!!! Meow!!!");
    }
}
상황을 상상해보세요. 우리는 모든 동물을 하나의 목록으로 모아 먹이를 준 다음 잠자리에 눕혀야 합니다. ArrayList동물( )을 생성하면 쉽게 할 수 있습니다 Animal. 그런 다음 각 동물에 해당하는 메서드를 호출합니다.
public class ZOO
{
    public static void main(String[] args)
    {
        List<Animal> allAnimals = new ArrayList<>();
        allAnimals.add(new Cat());
        allAnimals.add(new Wolf());
        allAnimals.add(new Fox());
        allAnimals.add(new YorkshireTerrier());
        for (Animal animal : allAnimals)
        {
            animal.eat();
            animal.sleep();
        }
    }
}
또는 animal메소드를 호출 할 수 없습니다 . 시트 에는 고양이, 늑대, 요릭, 여우가 포함되어 있지만 . 그리고 그들은 에 있는 메소드만 가지고 있습니다 . 이것은 매우 좋습니다. 모든 메서드를 호출할 수 있다면 왜 키보드 위에서 자는 늑대나 닭을 훔치는 요릭이 필요합니까? 관심을 가져주셔서 감사합니다. 이 기사가 귀하에게 도움이 되기를 바랍니다. 비판과 지적 환영합니다) bark()sleepOnKeyboard()allAnimalsAnimalAnimal
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION