프로그래밍 언어/JAVA

[JAVA] 타입변환과 다형성(polymorphism) (2)

김곰댕 2021. 7. 8. 16:25
728x90

하나의 배열로 객체 관리

 

예제)

package sec07.exam04_array_management;

public class Tire 
{
	public int maxRotation; //타이어의 최대 회전수(ex. 타이어가 약 1000번 회전하면 마모가되서 교체해야함)
	public int accumulatedRotation; //누적 회전수
	public String location; //타이어의 위치
	
	public Tire(String location, int maxRotation)
	{
		this.location = location;
		this.maxRotation = maxRotation;
	}
	
	//누적 회전수가 최대 회전수보다 작은 경우에 true반환
	public boolean roll()
	{
		//한 번 메소드가 실행될때마다 1증가
		++accumulatedRotation;
		
		if(accumulatedRotation < maxRotation)
		{
			System.out.println(location + "Tire 수명:" + (maxRotation-accumulatedRotation));
			return true;
		}
		else
		{
			System.out.println("***" + location+ "Tire 펑크 ***");
			return false;
		}
	}
}
package sec07.exam04_array_management;

public class HankookTire extends Tire 
{
	public HankookTire(String location, int maxRotation)
	{
		//부모의 생성자 사용
		super(location,maxRotation);
	}
	
	@Override
	public boolean roll() 
	{
		++accumulatedRotation;
		
		if(accumulatedRotation < maxRotation)
		{
			System.out.println(location + "HankookTire 수명:" + (maxRotation-accumulatedRotation));
			return true;
		}
		else
		{
			System.out.println("***" + location+ "HankookTire 펑크 ***");
			return false;
		}
	}
}
package sec07.exam04_array_management;

public class KumhoTire extends Tire 
{
	public KumhoTire(String location, int maxRotation)
	{
		//부모의 생성자 사용
		super(location,maxRotation);
	}
	
	@Override
	public boolean roll() 
	{
		++accumulatedRotation;
		
		if(accumulatedRotation < maxRotation)
		{
			System.out.println(location + "KumhoTire 수명:" + (maxRotation-accumulatedRotation));
			return true;
		}
		else
		{
			System.out.println("***" + location+ "KumhoTire 펑크 ***");
			return false;
		}
	}
}
package sec07.exam04_array_management;

public class Car 
{
	Tire[] tires = {
		new Tire("앞왼쪽",6),
		new Tire("앞오른쪽",2),
		new Tire("뒤왼쪽",3),
		new Tire("뒤오른쪽",4)
	};

	
	int run() //0이 return되면 모든 타이어가 정상적으로 굴러가고 있다.
	{
		System.out.println("[자동차가 달립니다.]");
		for(int i = 0; i<tires.length; i++)
		{
			if(tires[i].roll() == false) //타이어가 펑크나면
			{
				stop(); //멈추고
				return i+1; //어떤타이어에 문제가 있는지 반환
			}
			 
		}
		return 0;
	}
	
	void stop()
	{
		System.out.println("[자동차가 멈춥니다.]");
	}
}
package sec07.exam04_array_management;

public class CarExample 
{
	public static void main(String[] args) 
	{
		Car car = new Car();
		for(int i = 1; i<=5; i++)
		{
			int problemLocation = car.run(); //어느 부분의 타이어가 문제가 있는지 저장
			if(problemLocation != 0)
			{
				//car.tires[problemLocation-1].location : 타이어가 펑크난 위치
				System.out.println(car.tires[problemLocation-1].location + "HankookTire로 교체");
				car.tires[problemLocation-1] = new HankookTire(car.tires[problemLocation-1].location,15); //타입변환
			}
			System.out.println("--------------------------------");
		}
	}
}

출력 결과

 

매개변수의 다형성

매개변수가 클래스 타입일 경우 : 해당 클래스의 객체를 대입하는 것이 원칙이나 자식 객체를 대입하는 것도 허용된다.

- 자동 타입 변환

- 매개변수의 다형성

 

예제)

package sec07.exam05_method_polymorphism;

public class Vehicle 
{
	public void run()
	{
		System.out.println("차량이 달립니다.");
	}
}
package sec07.exam05_method_polymorphism;

public class Taxi extends Vehicle
{
	@Override
	public void run() 
	{
		System.out.println("택시가 달립니다.");
	}
}
package sec07.exam05_method_polymorphism;

public class Bus extends Vehicle
{
	@Override
	public void run() 
	{
		System.out.println("버스가 달립니다.");
	}
}
package sec07.exam05_method_polymorphism;

public class Driver 
{
	public void dirve(Vehicle vehicle) //vehicle 자신의 객체가 들어올 수도 있지만 자식 객체가 들어올 수도 있음
	{
		vehicle.run();
	}

}
package sec07.exam05_method_polymorphism;

public class DriverExample {

	public static void main(String[] args) 
	{
		Driver driver = new Driver();
		
		Bus bus = new Bus();
		Taxi taxi = new Taxi();
		
		driver.dirve(bus); //부모의 run이 실행되는것이 아닌 bus 객체의 run이 실행됨
		driver.dirve(taxi); //부모의 run이 실행되는것이 아닌 taxi 객체의 run이 실행됨
	}
}

출력 결과

 

강제 타입 변환(Casting)

부모 타입을 자식 타입으로 변환하는 것을 말한다. (자식타입을 부모타입으로 바꾸는 자동 타입변환과 반대)

조건

- 자식타입이 부모 타입으로 자동 변환된 이후 다시 자식 타입으로 변환할 때만 유효

강제 타입 변환이 필요한 경우

- 자식 타입이 부모 타입으로 자동 변환되면, 부모 타입에 선언된 필드와 메소드만 사용 가능

- 자식 타입에 선언된 필드와 메소드를 다시 사용해야 한다면 강제 타입 변환이 필요

 

객체 타입 확인(instanceof)

부모 타입이면 모두 자식 타입으로 강제 타입 변환 할 수 있는 것이 아니다.

- ClassCastException 예외가 발생할 수도 있다.

Parent parent = new Parent(); //애초에 child 객체가 만들어져서 자동타입변환이 된것이라면 가능
Child child = (Child) parent; //강제 타입변환을 할 수 없음

먼저 자식 타입인지 확인 후 강제 타입을 해야 한다.

boolean result = 좌항(객체) instansceof 우항(타입)  // 좌측의 객체가 우측의 타입으로 만들어졌는지 확인

 

예제)

package sec07.exam07_instanceof;

public class Parent 
{

}
package sec07.exam07_instanceof;

public class Child extends Parent
{

}
package sec07.exam07_instanceof;

public class InstanceofExample 
{
	public static void method1(Parent parent)
	{
		if(parent instanceof Child) //객체 타입 확인
		{
			Child child = (Child) parent;
			System.out.println("method1 - Child로 변환 성공");
		}
		else
		{
			System.out.println("method1 - Child로 변환되지 않음");
		}
	}
	
	public static void method2(Parent parent)
	{
		Child child = (Child) parent;
		System.out.println("method1 - Child로 변환 성공");
	}
	
	public static void main(String[] args) 
	{
		Parent parentA = new Child();
		method1(parentA);
		method2(parentA);
		
		Parent parentB = new Parent();
		method1(parentB);
		method2(parentB); //강제타입변환 검사를 하지않는 코드이므로 오류가 뜸
	}
}

출력 결과

 

728x90