Language/JAVA

[JAVA 기초 이론] 캐스팅 / instanceof / equals

오류나면꽥꽥 2023. 5. 11. 18:38

✅ instanceof 연산자

 

  • 객체가 특정 클래스의 인스턴스인지를 확인하는데 사용
  • 형 변환 전에 instanceof 연산자를 사용하여 객체의 타입을 확인하여 안전하게 형 변환을 수행
if (animal instanceof Dog) {
    Dog dog = (Dog) animal; // 안전한 다운캐스팅
}

 

캐스팅?

데이터 타입을 변환하는 과정

 

 

 

 

 

✋ instanceof를 사용하는 이유

 

▶ 안전한 형 변환

 

▶  instanceof 연산자는 객체 지향 프로그래밍에서 객체의 타입을 동적으로 확인하고 처리할 때 유용하게 사용

 

 

 

 

 

 

ex)

class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }

    public void wagTail() {
        System.out.println("Dog wags tail");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Cat meows");
    }

    public void purr() {
        System.out.println("Cat purrs");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

        // instanceof 연산자를 사용하여 객체의 타입을 확인
        if (animal1 instanceof Dog) {
            System.out.println("animal1 is a Dog");
        }

        if (animal2 instanceof Cat) {
            System.out.println("animal2 is a Cat");
        }

        // instanceof 연산자를 사용하여 다운캐스팅을 안전하게 수행
        if (animal1 instanceof Dog) {
            Dog dog = (Dog) animal1;
            dog.wagTail(); // 다운캐스팅 후에는 Dog 클래스의 메서드를 호출할 수 있음
        }
    }
}

 

출력)

더보기

animal1 is a Dog

animal2 is a Cat

Dog wags tail

 

 

 

 

 

 

✅ equals 메서드

 

  • 두 객체가 동일한지를 비교하는 데 사용
  • Object 클래스에서 상속된 equals 메서드가 객체의 참조값(주소)을 비교하도록 구현
  • 두 객체가 동일한 메모리 위치를 참조하는지를 확인
  • 객체의 필드 값을 비교하도록 재정의 ( ex, String 클래스의 equals 메서드는 두 문자열의 내용을 비교 )

 

 

 

 

 

✋ equals 메서드 사용하는 이유

 

 객체의 동일성을 올바르게 비교하는 것은 프로그램의 정확성과 안정성을 보장하는 데 중요

 

 

 

 

 

 

📍 equals 사용법

 

  1. 오버라이딩 생성 @Override

  2. 객체명.equals(객체명)
    ex) p1.equals(p2) == p1이랑 p2가 같은 주소야?
// object 클래스로 자동 업캐스팅
public boolean equals(Object obj) {
    Pokemon pokemon=(Pokemon)obj; // 다운 캐스팅
    if(this.name.equals(pokemon.name)) { // 객체 비교
        return true;
    }
    return false;
}

 

 

 

 

 

 

ex)

class MyClass {
    private int number;
    private String text;

    public MyClass(int number, String text) {
        this.number = number;
        this.text = text;
    }

    // equals 메서드 재정의하여 객체의 필드 값을 비교
    @Override
    public boolean equals(Object obj) {
        // 객체가 자기 자신인지 확인
        if (this == obj) {
            return true;
        }
        
        // obj가 null이거나 MyClass 클래스가 아닌지 확인
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        
        // obj를 MyClass 타입으로 형 변환하여 내용 비교
        MyClass other = (MyClass) obj;
        return number == other.number && text.equals(other.text);
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj1 = new MyClass(1, "Hello");
        MyClass obj2 = new MyClass(1, "Hello");
        MyClass obj3 = new MyClass(2, "World");

        // equals 메서드를 사용하여 두 객체의 내용 비교
        System.out.println("obj1 equals obj2: " + obj1.equals(obj2)); 
        System.out.println("obj1 equals obj3: " + obj1.equals(obj3)); 
    }
}

 

출력)

더보기
obj1 equals obj2: true

obj1 equals obj3: false

 

 

 

 

 

 

ex)

// 상속 심화
class Pokemon{
    String name;
    
    Pokemon(){
        this("포켓몬");
    }
    
    Pokemon(String name){
        this.name=name;
    }
    
    void printInfo(){
        System.out.println("이 포켓몬은"+this.name+"입니다.");
    }
    
    // 오버라이딩: 메서드 시그니처가 같아야함
    @Override
    public boolean equals(Object obj) {

        // 명시적 형변환, 다운 캐스팅	
        Pokemon pokemon=(Pokemon)obj;
        if(this.name.equals(pokemon.name)) {
            return true;
        }
        return false;
    }
}

class Pika extends Pokemon{
    Pika(){
        super("피카츄");
    }
}

class Charmander extends Pokemon{
    Charmander(){
        super("파이리");
    }
}

public class Test01 {
    public static void main(String[] args) {

        Pika p1=new Pika();
        Pika p2=new Pika();
        Charmander c1=new Charmander();

        //키우미집
        // 포켓몬-1 / 포켓몬-2
        // 피카츄 피카츄 -> 알 o
        // 피카츄 파이리 -> 알 x

        //p1 c1을 키우미 집에 맡겼다
        // 객체를 비교할 때는 두개의 객체가 같은 주소야? xxx ex) p1과 c1이 같은 포켓몬이야?
        // 연산자의 대상이 객체가 될 수 없음!
        // ex) 문자열
        // p1.equals(p1) : equals() 메서드는 두개의 객체가 같은 주소일 때 T
        
        if(p1.equals(p2)) {
            System.out.println("알을 획득했습니다!");
        }
        else {
            System.out.println("....");
        }
    }
}