자바/자바 입문 공부일지

자바 기초 공부 일지 24. 메소드 오버라이딩, instanceof 연산자

Tomitom 2022. 10. 31. 09:55
반응형

용어가 비슷하지만 다른 기능 중에 메소드 오버로딩이 있었어요. 

이거랑 메소드 오버라이딩의 차이점을 먼저 확인할게요. 

 

https://blue-dot.tistory.com/57

 

자바 기초 공부 일지 15. 메소드 오버로딩, this 참조 변수

● 메소드 오버로딩이란 같은 이름의 메소드를 중복으로 만들 때를 의미합니다. 자바에서 한 클래스에 같은 이름의 메소드를 두 개 이상 받을 수 없지만, 매개변수의 개수 혹은 타입을 다르게

blue-dot.tistory.com

 

메소드 오버로딩

반환형이고 이름이 같을 때, 그러나 매개변수가 다를 경우. 

호출 시에 전달 인자를 보고 사용할 메소드를 최종적으로 결정하는 것입니다. 

즉, 여러 메소드를 하나의 이름으로 정의하는 것이었습니다. 

 

메소드 오버라이딩은 

반환형, 이름,  매개변수까지 다 똑같은 함수에 새롭게 덮어쓰는 형태입니다. 

자식 클래스가 물려받은 메소드의 기능을 다시 정의해서 사용합니다. 

부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 형의 메소드로 다시 정의하는 것입니다. 

 

자바에서 자식클래스는 부모 클래스의 private 멤버를 제외한 모든 메소드를 상속 받습니다. 

부모 클래스 참조 변수는 자식 클래스의 객체까지도 참조 가능합니다.

이것은 클래스의 다형성이라고 합니다. 

 

아래 딸기치즈케이크 인스턴스 예제로 확인해볼게요. 

 

class Cake {

   public void sweet() {...}

}

 

케이크 클래스가 만들어집니다. 

 

class CheeseCake extends Cake {

   public void milky() {...}

}

 

케이크 클래스를 상속받은 치즈 케이크 클래스가 만들어집니다. 

 

class StrawberryCheeseCake extends CheeseCake {

   public void sour() {....}

}

 

치즈 케이크를 상속받은 딸기치즈케이크 클래스가 만들어졌어요. 

 

Cake cake1 = new StrawberryCheeseCake();

CheeseCake cake2 = new StrawberryCheeseCake();

 

처음의 부모 클래스인 케이크가 자식 클래스인 딸기치즈케이크를 참조해서 케이크 1을 만들 수도 있고

두 번째 생성된 치즈 케이크가 자식 클래스인 딸기치즈케이크를 참조해서 케이크 2를 만들 수 있습니다.

그러나 이 경우 접근 권한은 케이크의 기능에만 국한이 됩니다.

 

윤성우의 열혈 자바 프로그래밍 참조

 

 

즉 자식 클래스 참조 변수는 부모 클래스  참조 변수나 객체를 참조할 수 없습니다. 

개발네발 그림..

 

 

아래의 예제를 볼게요. 참조가 가능한 경우와 가능하지 않은 경우가 있습니다. 

 

class Cake {
   public void sweet() {...}
}
class CheeseCake extends Cake {
   public void milky() {...}
}
CheeseCake ca1 = new CheeseCake();
Cake ca2 = ca1;      //  가능!
Cake ca3 = new CheeseCake();
CheeseCake ca4 = ca3;       //  불가능!

 

 

 


오버 라이딩이란 부모 클래스로부터 받은 메소드를 자식 클래스에서 재정의 하는 것 입니다. 

메소드 오버 라이딩의 주 목적은 동일한 목적 또는 컨셉의 메소드를 자식 클래스에서 다르게 사용하고자 하는 것입니다. 

 

class Cake {

   public void yummy() {

      System.out.println("Yummy Cake");

   }

}

 

부모 케이크가 가지고 있는 야미 메소드 

 

class CheeseCake extends Cake {

   public void yummy() {

      System.out.println("Yummy Cheese Cake");

   }

}

 

자식 치즈케이크가 야미 메소드를 오버 라이딩 

 

메소드 오버라이딩의 사용할 때의 예제를 하나 더 볼게요. 

 

package day15;



class Water{
	void drinking() {
		System.out.println("마신다.");
	}
}


class HotWater extends Water{		//메소드 생성시 drinking() 메소드가 있는 상태입니다. 
	void drinking() {			// 뜨거운 물을 마시는 메소드를 다시 생성하고 싶을 때
    // 동일한 이름의 동일한 타입의 매개변수를 가지는 메소드를 그대로 가져온다. 
	System.out.println("호호 불며 조심스럽게 마신다."); //같은 객체의 메소드를 다시 쓴다 = 오버라이딩한다. 
	}
}

public class Inheritance05 {

	public static void main(String[] args) {

		HotWater hw = new HotWater();
		hw.drinking();

	}

}

package day15;



class Water{
    void drinking() {
        System.out.println("마신다.");
    }
}


class HotWater extends Water{       //메소드 생성시 drinking() 메소드가 있는 상태입니다.
    void drinking() {           // 뜨거운 물을 마시는 메소드를 다시 생성하고 싶을 때 동일한 이름의 동일한 타입의 매개변수를 가지는 메소드를 그대로 가져온다.
        System.out.println("호호 불며 조심스럽게 마신다."); // 같은 객체의 메소드를 다시 쓴다 = 오버라이딩 한다.
    }
}

public class Inheritance05 {

    public static void main(String[] args) {

        HotWater hw = new HotWater(); //오버라이딩을 하면 다양한 방식으로 참조가 가능 (절약적)  
        hw.drinking();      //비슷한 명칭을 여러번 쓰지 않아도 된다. ex) test01, test02, test03 ...
       

    }

}

TIP)

super : 상위 클래스를 뜻하는 키워드

super() : 상위 클래스 생성자

super. : 상위 클래스에 있는 ~

 


●instanceof 연산자

 

if(ref instanceof ClassName)

 refClassName 클래스의 인스턴스를 참조하면 true 반환

 refClassName를 상속하는 클래스의 인스턴스이면 true 반환

 

class Cake {

}

class CheeseCake extends Cake {

}

class StrawberryCheeseCake extends CheeseCake{

}

 

이렇게 상속을 했을 경우에 아래에서 참조형이 맞는지 확인을 해봅니다. 

 

public static void main(String[] args) {

   Cake cake = new StrawberryCheeseCake();

  

   if(cake instanceof Cake) {...}   // 케이크가 참조하고 있는 인스턴스가 케이크인지를 참과 거짓으로 반환 

  

   if(cake instanceof CheeseCake) {...}

   if(cake instanceof StrawberryCheeseCake) {...}

}

 

다형성에 따라 부모 클래스의 참조 변수는 자식 클래스를 참조할 수 있으므로 그에 따라 값을 출력할 것입니다.

 


여기까지 배운 것을 참고해서 예제를 하나 작성해볼게요. 

 

 

package day16;

class Cat {
	String name;

	Cat(){}
	Cat(String name){
		this.name = name;
		}
	
	void punch() {
		System.out.println("고양이펀치");
	}
}

// IS - A 관계 : 상속받은 자식 클래스가 부모 클래스에 포함되어야 한다. 
class Tiger extends Cat{
	Tiger(){
		super(); // 부모 클래스 생성자를 호출한다.
	}
	void punch() {
		System.out.println("호랑이 펀치");
	}
}


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

		
		Cat c = new Cat("국희");
		Tiger t = new Tiger();
		
		/* 부모 타입의 참조 변수가 자식 인스턴스 참조 가능 
		 참조는 가능하지만 자식에만 추가된 자원들은 자원 불가
		 메소드 오버라이딩 : 부모 클래스로부터 물려받은 메소드를 재정의한다 
		 참조 타입에 따라서 타입이 달라짐
		 다형성 아래에서도 메소드 오버라이딩을 하면, 
		 참조된 인스턴스 타입의 메소드를 호출할 수 있다. 
		*/ 
		Cat a = new Tiger(); 
		
		a.punch();
		t.punch();
		
		System.out.println(a instanceof Cat);
		//instanceof : 참조 중인지 혹은 참조 가능한지 확인이 가능합니다. 

	}

}

/*
 * 부모 타입이 자식 타입 객체를 참조해도, 메소드 사용이 가능하다. 
 * 비슷한 컨셉의 메소드를 정의할 때, 이름을 따로 정의하지 않아도 되는 편의가 있음 
 */

 

반응형