1. 타입캐스팅

참조 유형(클래스)을 저장하는 변수도 다른 유형으로 변환할 수 있습니다. 그러나 이것은 단일 유형 계층 구조 내에서만 작동합니다. 간단한 예를 살펴보겠습니다. 아래 클래스가 위 클래스를 상속하는 다음과 같은 클래스 계층 구조가 있다고 가정합니다.

타입캐스팅

기본 유형뿐만 아니라 참조 유형의 유형 변환도 확대 및 축소로 분류됩니다.

Cat 클래스는 Pet 클래스를 상속하고 Pet 클래스는 Animal 클래스를 상속합니다.

다음과 같이 코드를 작성하면:

Animal kitten = new Cat();

확장 유형 변환 입니다 . 암시적 캐스트라고도 합니다. 이제 Cat 객체 를 참조하도록 cat 참조를 확장했습니다 . 이와 같은 유형 변환을 사용하면 Cat 클래스에는 있지만 Animal 클래스에는 없는 메서드를 호출하기 위해 새끼 고양이 참조를 사용할 수 없습니다 .

축소 변환(또는 명시적 캐스트)은 반대 방향으로 발생합니다.

Cat cat = (Cat) kitten;

우리는 새끼 고양이 변수(타입이 Animal ) 에 저장된 참조를 Cat 타입으로 캐스트하기를 원한다고 명시적으로 표시했습니다 .



2. 객체 유형 확인

그러나 여기서 매우 조심해야 합니다. 이렇게 하면:

Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;

컴파일러는 이 코드를 허용하지만 프로그램이 실행될 때 오류가 발생합니다 ! JVM에서 예외가 발생합니다.

Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf

Cat 개체 에 대한 참조는 유형이 Cat 클래스의 조상인 Pet, Animal 또는 Object인 변수에만 저장할 수 있습니다.

왜 그런 겁니까?

여기서 중요한 점은 개체 참조가 해당 개체의 메서드와 변수를 참조하는 데 사용된다는 것입니다 . Cat 개체에 대한 참조를 저장하기 위해 Animal 변수를 사용한다면 문제가 없을 것입니다. Cat 유형에는 항상 Animal 유형의 변수와 메서드가 있습니다 .

그러나 JVM이 Cat 객체에 대한 참조를 Wolf 변수에 저장할 수 있도록 허용한 경우에는 grayWolf 변수를 사용하여 해당 변수에 저장된 Cat 객체에 존재하지 않는 메서드를 호출하려고 시도할 수 있습니다. . 그렇기 때문에 이 배치가 허용되지 않습니다.

instanceofJava 에는 객체가 특정 유형인지 확인하여 특정 유형의 변수에 저장할 수 있는 특수 연산자가 있습니다 . 매우 간단해 보입니다.

variable instanceof Type

예:

Animal beast = new Cat();
if (beast instanceof Wolf)
{
   Wolf grayWolf = (Wolf) beast;
}

이 코드는 런타임에도 오류를 일으키지 않습니다.

다음은 상황을 설명하는 몇 가지 예입니다.

확대 유형 변환 설명
Cow cow = new Whale();

이것은 고전적인 확장 변환입니다. 유형 변환 연산자가 필요하지 않습니다. 이제 클래스에 정의된 메서드만 개체 Cow에서 호출할 수 있습니다 Whale.

cow변수 에서 컴파일러는 해당 유형(클래스 Cow)에 있는 메서드만 호출할 수 있습니다.

축소 유형 변환
Cow cow = new Whale();
if (cow instanceof Whale)
{
   Whale whale = (Whale) cow;
}
클래식 축소 변환: 유형 검사 및 캐스트 연산자를 추가해야 합니다.
변수 는 개체 Cow cow에 대한 참조를 저장합니다 Whale.
이것이 사실인지 확인한 다음 (축소) 유형 변환을 수행합니다. 또는 다음과 같이 불리기도 합니다.
타입 캐스트
.

Cow cow = new Cow();
Whale whale = (Whale) cow; // Exception
개체 유형을 확인하지 않고 참조 유형을 좁힐 수 있습니다. 변수가 가 아닌 개체를 참조하는
경우 가 생성됩니다. cowWhaleInvalidClassCastException


3. 원래 메서드 호출: super키워드

부모 클래스의 메서드를 재정의할 때 우리 자신의 메서드로 교체하는 대신 약간만 보완하고 싶을 때가 있습니다.

메서드에서 부모 클래스의 메서드를 사용할 수 있고 우리 자신의 코드 중 일부를 실행할 수 있다면 멋질 것입니다. 또는 먼저 자체 코드를 실행한 다음 부모 클래스의 메서드를 호출할 수도 있습니다.

그리고 Java는 우리에게 바로 그것을 가능하게 합니다. 부모 클래스의 메서드를 호출하려면 다음을 수행하십시오.

super.method(arguments);

예:

class PeaceTime
{
   public double getPi()
   {
      return 3.14;
   }
}

class WarTime extends PeaceTime
{
   public double getPi()
   {
      return super.getPi()*2;  // 3.14*2
   }
}

전시에는 의 값이 Pi6보다 클 수 있습니다! 물론 우리는 농담을 하고 있지만 이 예는 이 모든 것이 어떻게 작동하는지 보여줍니다.

다음은 상황을 명확히 하기 위한 몇 가지 예입니다.

암호 설명
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.print("This is incorrect: ");
      super.printName();
      System.out.println("I'm a whale");
   }
}
Cow그리고 Whale수업
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printAll();
}
화면 출력은 다음과 같습니다.
I'm a white whale
This is incorrect: I'm a cow
I'm a whale

이것은 어려운 일입니다. 솔직히 OOP 에서 가장 어려운 것 중 하나입니다 . 즉, 당신은 그것을 알고 이해해야 합니다.