좋은 하루 되세요, 자바라쉬 사람. Java에서 참조 유형 캐스팅에 대한 질문을 받기 시작했습니다. 매번 같은 내용을 반복하지 않기 위해 짧은 글을 쓰기로 결정했습니다.
먼저 타입 캐스팅이 무엇인지 살펴보겠습니다.
유형 캐스팅(유형 변환)은 한 유형의 변수 값을 다른 유형의 값으로 변환하는 것입니다. 그것이 무엇인지, 무엇과 함께 먹는지에 대한 예를 살펴 보겠습니다. 몇 가지 클래스 계층 구조가 있습니다( 그림 1 참조 ). 여기에서 계층 구조의 모든 클래스, 누가 누구를 상속하는지, 각 클래스의 메서드를 볼 수 있습니다. 확장 및 축소 내전이 있습니다. 우리는 클래스Cat
가 클래스의 자손임을 알 수 있습니다 Pet
. Pet
는 클래스의 후계자입니다 Animal
. 우리가 쓸 때 :
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
이는 확장 형변환 (또는 암시적 형변환)입니다. 우리는 링크를 확장 animalCat
했습니다 animalDog
. Cat
그들은 객체 와 를 참조합니다 Dog
. 이러한 캐스트를 사용하면 에는 있지만 에는 없는 animalCat/animalDog
링크를 통해 메서드를 호출 할 수 없습니다 . 축소 (또는 명시적) 캐스트는 반대 방향으로 발생합니다. Cat/Dog
Animal
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
RunTime
Cat
두 가지 다른 클래스가 있음 을 알 수 있습니다 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()
allAnimals
Animal
Animal
GO TO FULL VERSION