다형성 (Polymorphism)

Brogod97·2022년 12월 23일
0

KH TIL

목록 보기
23/37
post-thumbnail

다형성

객체 지향 언어의 특징 중 하나로 ‘다양한 형태를 갖는다’라는 뜻으로 하나의 행동으로 여러 가지 일을 수행하는 개념.

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

작성 예시

    부모클래스 변수명 = new 자식 클래스();

자식 클래스끼리는 다형성을 이용할 수 없음!


클래스 형변환

업 캐스팅(Up Casting)

상속 관계에 있는 부모, 자식 클래스 간에
부모타입의 참조형 변수모든 자식 타입 객체의 주소를 참조할 수 있음

//Sonata 클래스는 Car 클래스의 후손

Car c = new Sonata();

//Sonata클래스형에서 Car클래스형으로 바뀜

이 때, 접근할 수 있는 객체의 정보는 부모로부터 상속받은 것들임

다운 캐스팅 (Down Casting)

자식 객체의 주소를 받은 부모 참조형 변수를 가지고 자식의 멤버를 참조해야 할 경우,
부모 클래스 타입의 참조형 변수를 자식 클래스 타입으로 형변환 하는 것

  • 자동으로 처리되지 않음 (강제 형변환 필요)
//Sonata 클래스는 Car 클래스의 후손

Car c = new Sonata();

((Sonata)c).moveSonata();

다형성 활용 예시

객체배열과 다형성

Car[] carArr = new Car[5];

carArr[0] = new Sonata();
carArr[1] = new Avante();
carArr[2] = new Grandure();
carArr[3] = new Spark();
carArr[4] = new Morning();

생성한 객체 배열의 타입이 부모 클래스의 타입일 경우,
해당 객체 배열의 내부에 부모 클래스 및 자식 클래스의 객체가 저장될 수 있음

매개변수와 다형성

다형성을 이용하여 메소드 호출 시 부모타입의 변수 하나만 사용해 자식 타입의 객체를 받을 수 있음

public void execute() {
	driveCar(new Sonata()); 
	driveCar(new Avante());
	driveCar(new Grandure());
}

public void driveCar(Car c) {}

만약, driveCar() 의 매개변수로 부모 타입의 값을 받지 않는다면, 각각 자식 타입의 값에 맞는 메소드를 정의해야 하기 때문에 코드 길이가 길어짐 (비효율적)


바인딩

실제 실행할 메소드 코드와 호출하는 코드를 연결 시키는 것

정적 바인딩

프로그램이 실행되기 전 컴파일 단계에서 메소드와 메소드 호출부를 연결

동적 바인딩

컴파일 시 정적 바인딩된 메소드를 실행할 당시의 객체 타입을 기준으로 바인딩 되는 것

동적 바인딩 성립 요건

상속 관계로 이루어져 다형성이 적용된 경우, 메소드 오버라이딩이 되어 있으면
정적으로 바인딩 된 메소드 코드보다 오버라이딩 된 메소드 코드를 우선적으로 수행

public class Car{
	 public String drive(){}
}

위 코드를 보면 부모 클래스 Car ➡ drive() 메소드를 멤버로 갖고 있음

public class Bentley enxtends Car{

@Override
public String drive(){ 
	  return “날다”;
}

Car를 상속받은 자식 메소드 Bentley ➡drive() 메소드를 재정의하고 있음

public static void main(String[] args) {
	Car b = new Bentley();
    
    b.drive();
}

위 처럼 자식 객체의 주소를 부모 타입 b에 저장한 상태에서 b.drive() 호출할 경우,

컴파일 단계에선 이를, Car.drive()로 인식함 ➡ [정적 바인딩]

그러나 실제로 실행 결과를 보면 재정의 된 drive() 가 호출된 것을 확인할 수 있는데,

이는 실행 이후에 오버라이딩 된 메소드가 호출되기 때문 ➡ [동적 바인딩]

0개의 댓글