[JAVA] 다형성

Ming·2022년 9월 26일
0

자바

목록 보기
5/14

다형성

조상 타입 참조 변수로 자손 타입 객체를 다루는 것이다.

class Tv{
	boolean power;
    int channel;
    
    void power() { power = !power }
    void channelUp() { ++channel; }
    void channelDown() { --channel; }
}
class SmartTv extends Tv{
	String test;
    
    void caption() { }
}
Tv t=new Tv();
SmartTv s = new SmartTv();

다형성

Tv t=new SmartTv();

다형성은 타입이 불일치하는 것도 허용한다.

객체와 참조변수의 타입이 일치할 때와 일치하지 않을 때 차이

  • 일치

    7개의 모든 기능을 사용할 수 있다.
  • 불일치

    리모컨은 tv 리모컨이지만 제품은 SmartTv이다. Tv 리모컨에는 멤버변수 5개만 존재하기 때문에 SmartTv는 5개의 기능(power, channel, power(), channelUp(), channelDown())만 사용할 수 있다. 즉, 여러 개의 기능을 갖고 있어도 Tv에 정의된 일부만 사용할 수 있다.

❗️자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.

SmartTv s=new Tv();  //에러

이와 같은 형태는 불가능하다. s는 기능이 7개인데 Tv의 기능은 5개이기 때문에 안된다. 없는 기능을 누르면 동작이 안되고 없는 기능을 호출했기 때문에 에러가 발생한다.

참조변수의 형변환

주소값, 객체가 바뀌는 것이 아닌 사용할 수 있는 멤버의 갯수를 조절하는 것이다.
✅ 참조 변수의 형변환 정리

  • 조상-자손 관계의 참조변수만 서로 형변환이 가능하다
  • 자손타입에서 조상타입으로 형변환(업캐스팅)을 할 때는 생략 가능하다
  • 조상타입에서 자손타입으로 형변환(다운캐스팅)을 할 때는 생략이 불가능하다(사용할 수 있는 기능이 더 추가되기 때문)

업캐스팅과 다운캐스팅

  • 업캐스팅(upcasting) : 부모 클래스 변수로 자식 클래스 객체를 참조할 수 있다
  • 다운캐스팅(downcasting) : 자식 클래스 변수로 부모 클래스 객체를 참조할 수 있다.
class Car{ }
class FireEngine extends Car { }
class Ambulance extends Car { }
FireEngine f = new FireEngine();
Car c = (Car)f;
Ambulance a = (Ambulance)f; //에러

객체 a의 경우 상속관계가 아닌 클래스 간의 형변환을 시도했기 때문에 에러가 발생한다.

  • 예시
    class Car{
    	String color;
    	int door;
    
    	void drive() {
    		System.out.println("drive");
    	}
    
    	void stop() {
    		System.out.println("stop");
    	}
    }
    
    class FireEngine extends Car {
    	void water() {
    		System.out.println("water");
    	}
    }
    
    public class Test{
    	public static void main(String args[]) {
    		Car car = null;
    		FireEngine fe = new FireEngine();
    		FireEngine fe2 = null;
    
    		fe.water();
    		car = fe; //형변환 생략
    		car.water(); //에러 
    		fe2=(FireEngine)car; //조상타입에서 자손타입으로 형변환을 할 때는 생략 불가능
    		fe2.water();
    	}
    }
    car.water()를 했을 때 Car 타입의 참조변수로는 water()를 호출할 수 없기 때문에 에러가 발생한다

instanceof 연산자

참조변수의 형변환 가능 여부를 확인할 때 사용한다. 형변환을 하기 전에 반드시 instanceof 연산자를 이용해 확인한 후에 형변환을 해야한다.

if(c instanceof FireEngine) { //형변환이 가능한지 확인
	FireEngine fe = (FireEngine)c;
}

c가 가리키는 객체가 FireEngine으로 형변환이 가능한지 확인 후 true가 반환되면 형변환을 진행하면 된다.

✅ 객체 instanceof Object 인 경우 Object는 모든 클래스의 최고 조상이기 때문에 항상 true가 반환된다.

매개변수의 다형성

참조형 매개변수는 매서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.

class Product {
	int price;
    int bonusPoint;
}

class Tv extends Product{ }
class Computer extends Product { }
class Audio extends Product { }

class Buyer {
	int money = 1000;
    int bonusPoint = 0;
}
//아래 3개의 함수는 오버로딩
void buy(Tv t) {
	money -= t.price
    bonusPoint += t.bonusPoint;
}
void buy(Computer c) {
	money -= c.price;
    bonusPoint += c.bonusPoint;
}
void buy(Audio a) {
	money -= a.price;
    bonusPoint += a.bonusPoint;
}

구매자가 물건을 사기 위해 buy()를 추가하려고 할 때 물건마다 함수를 추가해주어야한다. 많은 메서드를 오버로딩해야하고 코드 중복도 발생한다.

Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
void buy(Product p) {
	money -= p.price;
    bonusPoint += p.bonusPoint;
}

매개변수를 조상타입인 Product를 사용하게 되면 이 함수하나로 여러 물건 구매가 가능하다. 조상타입의 참조변수로 자손타입의 참조변수를 가리킬 수 있기 때문이다.

여러 종류의 객체를 배열로 다루기

조상타입의 배열에 자손들의 객체를 담을 수 있다.

Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
Product[] p = {(new Tv(), new Computer(), new Audio()}
//또는
Product[] p = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();

vector 클래스

  • 가변 배열 기능을 찾고 있는 클래스이다. add()를 이용하면 알아서 배열의 길이를 늘려서 저장을 해준다.
  • Vector 클래스에 있는 Object 배열을 갖고 있기 때문에 모든 종류의 객체를 저장할 수 있다.(Object는 모든 클래스의 최고 조상)

✅ 다형성의 장점

  • 다형성 매개변수 ( 함수하나로 여러 물건 구매가 가능하다)
  • 하나의 배열로 여러 종류 객체 다룰 수 있다.

[출처]
자바의 정석 - https://www.youtube.com/playlist?list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp

0개의 댓글

관련 채용 정보