JAVA Programming

Growing_HJ·2024년 5월 28일

일기장

목록 보기
9/51

2024.05.24. FRI
A. Polymorphism (폴리모피즘, 다형성)
=> 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 하는 것.
=> 타입변화 (), casting을 의미.

Tv t = new Tv(); // 기반 클래스
TvVcr tvcr = new TvVcr(); // 파생(된) 클래스
TvCaption tvca = new TvCaption(); // Tv로 부터 파생된 클래스
Tv t = new TvVcr(); // 자바에서의 다형성, 인스턴스는 TvVcr인데, 참조 변수의 타입은 Tv인 기반 클래스 타입. 
Tv t = new TvCaption();

==> Tv라는 하나의 타입으로 TvVcr, TvCaption의 인스턴스 타입으로 표현.

**
A. TvVcr tvcr = new TvVcr();

  • 메모리의 인스턴스는 TvVcr.
  • 참조변수의 타입이 기반 클래스임.
  • 따라서, 기반 클래스의 범위 내에서 사용 가능.
  • 인스턴스 사용에 사용제한이 있음.
  • 비론 인스턴스는 TvVcr 이지만, Tv의 멤버들만 사용가능하다.
  • TvVcr이지만, Tv의 멤버들만 사용이 가능.
  • 그래서, TvVcr의 모든 것을 사용하려면 down casting이 필요.
    B. TvVcr tvcr = new TvVcr();
  • 메모리의 인스턴스는 TvVcr임.
  • 따라서, 파생 클래스 자신의 범위내에서 사용 가능.
  • 인스턴스 사용에 제한 없음.
Tv tv = new Tv();
Tv tv = new TvVcr();
Tv tv = new TvCamera();
Tv tv = new TvGame();
Tv tv = new TvCdPlayer();
  • 다양한 타입의 인스턴스들을 하나의 타입으로 표현.
 *   
 *   Tv[0] = new TvVcr();
 *   Tv[1] = new TvCamera();
 *   Tv[2] = new TvGame();
 *   Tv[3] = new TvCdPlayer();
  • 형변환(casting)
  1. up casting : 파생(자식) -> 기반(부모), 자동형변환
    자바는 단일상속만 허용. 파생 입장에서 부모는 하나임으로 자동 형변환.
  2. down casting : 기반(부모) -> 파생(자식), 명시적 형변환
  • 기반 입장에서는 파생이 경우에 따라서 여러개 일 수 있으므로,down casting 대상이 누가 될 지 알 수 없으므로, 명시적 형변환.

  • instanceof 연산자
    메모리 상의 인스턴스 상태까지 고려해주는 것은 아님.
    그래서, 상속관계의 상태만 고려해주는 것임.
    참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보는 용도로 사용.

  • 다형성의 활용과 instanceof 의 용도
    매개변수를 활용한 다형성 => 메소드의 매개변수가 다형성을 띄고 있다.
    전달된 인스턴스의 참조변수의 타입에 따라 해당 인스턴스의 멤버변수 사용시 범위를 알 수 있기 때문.
    UpCasting, DownCasting 예제코드)

// 참조변수 형변환 클래스
class Car{
	String color;
	int door;
	void drive() {
		System.out.println("운행중");
	}
	void stop() {
		System.out.println("정지");
	}
}
class FireEngine extends Car{
	void water() {
		System.out.println("화재 진압중");
	}
}
class Ambulance extends Car{
	void siren() {
		System.out.println("사이렌중");
	}
}
public class CastingEx {
	public static void main(String[] args) {
		// 참조변수 형변환 관련 클래스
		Car car = null;
		FireEngine fe = new FireEngine();
		FireEngine fe2 = null;
		
		fe.water();
		car = fe;
		car = (Car)fe;
		//Car 참조변수의 인스턴스 사용 범위 고려
		//car.water(); // 파생 인스턴스의 멤버를 사용할 수 없음.
		fe2 = (FireEngine)car;	// down casting, 명시적 형변환이 필요
        fe2.water();
		
		// == Down Casting 시 고려해야 할 사항
		// 업 캐스팅, 다운 캐스팅 모두 다 되는 경우와 아닌 경우가 있음,
		Car car2 = new Car();
		Car car3 = null;
		FireEngine fe3 = null;
		
		car2.drive();
FireEngine fe4 = new FireEngine();
		// 1. UpCasting 가능여부 확인 코드
		if(fe4 instanceof FireEngine) {
			System.out.println("Up Casting - FireEngine instance");
			FireEngine fe5 = (FireEngine)fe4;
		}
		if(fe4 instanceof Car) {
			System.out.println("Up Casting- Car instance");
			Car car4 = (Car)fe4;
		}
		if(fe4 instanceof Object) {
			System.out.println("Uo Casting - Object instance");
			Object obj = (Object)fe4;
		}
		
		// 2. Down Casting 가능여부 확인 코드
		Object fe5 = new FireEngine();
		if (fe5 instanceof Object) {
			System.out.println("Down Casting - Object instance");
			Object obj = (Object)fe4;			
		}
		if(fe5 instanceof Car) {
			System.out.println("Down Casting - Car instance");
			Car obj = (Car)fe5;
		}
		if(fe5 instanceof FireEngine) {
			System.out.println("Down Casting - FireEngine");
			FireEngine obj = (FireEngine)fe5;
		}
		if(fe5 instanceof Ambulance) {
			System.out.println("Down Casting - Ambulance");
			Ambulance obj = (Ambulance)fe5;
		}
	}
}        
  • 반환타입을 활용한 다형성 => 메소드의 반환타입이 다형성을 띄고 있다.
    메소드를 호출한 쪽에서 현재 참조변수가 누구의 인스턴스인지 확인이 필요한 경우가 있기 때문.
    (매개변수를 활용하는 메소드의 경우, 반환형이 있는 메소드 (void 메소드는 제외) 경우),
    오버로딩을 통해서 동일한 기능을 하는 메소드가 많아지면, 유지보수가 힘들어 짐으로
    기반 클래스 타입으로 매개변수와 반환형을 적용하면, 관리해야 할 메소드가 줄어듬으로
    유지보수가 간편해 질 수 있는 장점이 있음.

참조변수와 인스턴스의 연결 예제코드)

//참조변수와 인스턴스의 연결 관련 클래스 1 
class Parent {
	int x = 100;
	void method() {
		System.out.println("Parent3 : method()");
	}
}
class Child extends Parent{
	int x = 200;
	
	//메소드 오버라이딩
	void method() {
		System.out.println("Child3 : method()");
	}
}

//참조변수와 인스턴스의 연결 관련 클래스 2
// => 기반 클래스에만 멤버가 있는 경우, 파생 클래스에 멤버가 없는 경우
class Parent2 {
	int x = 100;
	
	void method() {
		System.out.println("Parent4 : method()");
	}
}
class Child2 extends Parent2 {
	
}

public class ConnectEx {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	//Casting 후 사용되는 <멤버 변수>와 <멤버 메소드>를 확인
		Parent p = new Child();
		Child c = new Child();
		
		//오버라이드가 된 상태에서 Up Casting 인 경우. 
		//멤버 변수를 사용하는 경우, -> 참조변수의 타입을 따라감,
		//멤버 함수를 사용하는 경우, -> 인스턴스 클래스 타입을 따라감. 
		
		//참조변수의 타입이 Parent 인 경우
		//Child의 멤버변수 및 멤버 메소드 사용.
		//Up Casting가 되었다고 가정 => 기반 클래스의 멤버를 사용하려는 목적
		System.out.println("p.x = " + p.x);	//기반 멤버
		p.method();
		
		//참조 변수의 타입이 Parent인 경우
		//Child의 멤버변수 및 멤버 메소드 사용
		System.out.println("c.x = " + c.x);	//파생멤버
		c.method();							//파생멤버 
		
		// 참조변수와 인스턴스의 연결 관련 클래스2. 
		// 기반클래스에만 멤버가 있는 경우, 파생클래스에 멤버가 없는 경우
		Parent2 p2 = new Child2();
		Child2 c2 = new Child2();
		
		System.out.println("p2.x = " + p2.x);	//기반멤버
		p.method();							//파생멤버
		System.out.println("c2.x = " + c2.x);
		c.method();
	}
}

0개의 댓글