09_Polmorphism(1)

김정욱·2022년 12월 22일
0

JAVA 복습

목록 보기
9/15
post-thumbnail
post-custom-banner

<다형성>

1. 다형성

  • 상속 + 컴퓨터 연산규칙(같은 자료형끼리만 연산 가능) + 얕은 복사

1) 정의

  • 상속을 이용한 기술로 부모 클래스 타입의 참조변수 하나로, 상속관계에 있는 여러타입의 자식 객체를 참조할 수 있는 기술

2) 업캐스팅(Up Casting)

  • 상속관계에 있는 클래스간에 부모타입의 참조형 변수가 모든 자식 타입 객체의 주소를 참조할 수 있다
  • 자동으로 형변환이 일어난다
부모클래스 변수명 = new 자식클래스();
--------------------------------------------------
Car c = new Tesla();

부모타입의 변수를 통해서 접근할 수 있는 객체의 정보는 부모로 부터 상속받은 멤버만 참조 가능하다.

public class Car(){
	private String Engine;
    private String fuel;
    private int wheel;
    ...
}

public class Tesla extends Car(){
	private int batteryCapacity;
    ...
   
    public int batteryChangePrice(){
    	int result = 0;
       
        if(batteryCapaciy <= 1000) result = 1000;
        else if (batteryCapaciy <= 2000) result = 2000;
        else result = 3000;
       
 		return result;       
    }
} 
import ...Car;
import ...Tesla;

public class Service(){
	Car c = new Tesla();

	c.getEngine();	// 가능
    c.getFuel();	// 가능
    c.getWheel();	// 가능
    c.getBatteryCapacity(); // 불가능
    c.batteryChangePrice();	// 불가능

-> batteryCapacity변수와 batteryChangePrice메소드는
Tesla(자식)의 고유멤버이므로 Car(부모) 타입의 참조변수 c는 호출할 수가 없다

3) 다운캐스팅(Down Casting)

  • 자식 객체의 주소를 받은 부모타입의 참조형 변수를 이용하여 자식객체의 고유 멤버를 참조해야 할 경우 사용
  • 부모 클래스 타입의 참조형 변수를 자식 클래스 타입으로 강제형변환 하는 것
  • 자동으로 일어나지 않기 때문에 반드시 자식 타입을 명시하여 형변환
Car c = new Tesla();
((Tesla)c).batteryChangePrice();

-> (Tesla)c.batteryChangePrice(); 의 경우 "." 연산자가 "(자료형)" 강제형변환 연산자보다
연산이 우선순위에 있으므로 형변환이 일어나기전에 메소드 호출이 진행된다
그러므로 ()를 이용하여 형변환이 먼저일어나도록 해줘야 한다

4) 객체배열과 다형성

  • 다형성을 이용하여 상속 관계에 있는 하나의 부모 클래스 타입의 배열을 만들고, 여러종류의 자식 클래스 객체를 저장한다
Car[] carArr = new Car[3];

carArr[0] = new Tesla();
carArr[1] = new Spark();
carArr[2] = new Sonata();

5) 매개변수와 다형성

  • 다형성을 이용하여 메소드 호출시에 매개변수를 부모 타입의 매개변수로 지정해서 자식 타입의 객체를 받을 수 있음
public void execute(){
	driveCar(new Tesla()); // Car t = new Tesla(); -> driveCar(t);
    driveCar(new Spart());
    driveCar(new Sonata());
}

public void driveCar(Car temp){}

6) 바인딩

  • 실제 실행할 메소드와 호출하는 코드를 연결 시키는 것
  • 정적바인딩, 동적바인딩이 있다
<정적바인딩>
Car c1 = new Car("경유엔진", "경유", 8);
System.out.println(c1.toString());
------------------------------------------------------------------
=> 프로그램 실행 전 컴파일러는 toString() 메소드가 Car에 있는걸로 인식해서 
c1.toString() 호출코드와 String edu.kh.poly.model.vo.Car.toString()
메소드 코드를 연결한다 -> 정적바인딩
※toString()은 필드 값들을 리턴하는 메소드로 오버라이딩 함
<동적바인딩>
Car c2 = new Tesla("경차엔진", "휘발유", 4, 20000);
-> 업캐스팅 되어 있는 상태, 부모 멤버만 참조 가능한 상태
System.out.println(c2.toString());
------------------------------------------------------------------
=> String edu.kh.poly.model.vo.Car.toString() 연결,
c2가 Car 타입이므로 toString()Car toString()을 호출 (정적바인딩)

막상 시행해보면 부모 멤버인 engine, fule, wheel 뿐만 아니라
batteryCapacity의 값도 같이 출력된다., TeslatoString()이 호출됨

컴파일 : 부모(Car)와 바인딩 -> 정적바인딩
실행 : 자식(Tesla)의 오버라이딩된 메소드와 바인딩 ->동적바인딩

장점 : 업캐스팅된 상태에서 다운캐스팅 없이 자식의 오버라이딩된 메소드를 수행

7) instanceof 연산자

  • 현재 참조형 변수가 어떤 클래스 형의 객체 주소를 참조하고 있는지를 확인 할 때 사용. 클래스의 타입이 맞으면 true, 틀리면 false 반환
if(레퍼런스 instanceof 클래스타입){
	true일 때 처리할 내용, 해당 클래스 타입으로 down casting
} 
----------------------------------------------------------
if(c instanceof Tesla){
	int result = ((Tesla)c).getBatteryCapacity();
} else if (c instanceof Spark){
	double result = ((Spark)c).getDiscountOffer();
} 
profile
절박한 마음을 갖고 하루를 보내자!!
post-custom-banner

0개의 댓글