프로그래밍/java

[자바JAVA] 다형성(동적바인딩, 클래스형변환)

pupu91 2022. 7. 14. 13:11
반응형


다형성

객체지향 프로그래밍의 3대특징
1 . 캡슐화
2 . 상속
3 . 다형성



  • 하나의 인스턴스가 여러가지 타입을 가질 수 있는 것을 의미
  • 결합도를 낮춰 유지보수성과 생산성 증가
  • 상속 관계에 있는 모든 객체는 동일한 메시지를 수신할 수 있음
  • 확장성이 좋은 코드 작성 가능



1 . 다형성 구현 : 동적바인딩

  • 동적바인딩 : 컴파일시에는 해당 타입의 메소드와 연결되어 있다가 실행 시간(runtime)에 실제 객체가 가진 오버라이딩 된 메소드로 바인딩이 바뀌어 동작하는 것
  • 상속 관계로 이루어져 다형성이 적용되어야하고 메소드 오버라이딩이 되어 있어야 함.
  • 하나의 메소드 호출로 각기 다른 객체의 다른 메소드를 동작 시키게 함




2 . 클래스 형변환 (class type casting)

  • 객체별로 고유한 기능은 동작시키지 못하므로 레퍼런스 변수를 형변환하여 사용해야함


((클래스타입)레퍼런스). 고유기능();

구분 up - casting down-casting
형변환 상위 타입으로 형변환 하위 타입으로 형변환
표현법
Car c = (Car)new Sonata();
묵시적
Car c = new Sonata();
명시적
((Sonata)c).moveSonata();

  • 타입 형변환을 잘 못하는 경우 컴파일 시에는 문제되지 않고 런타임시 에러(ClassCastException) 발생

=> 오류 발생을 방지 하기 위해 instanceof 연산자를 이용해 레퍼런스 변수와 클래스 타입의 동일 여부를 확인할 수 있음.클래스 타입이 맞으면 true, 맞지 않은면 false를 반환

◇instanceof 사용

if(레퍼런스 instanceof 클래스타입){
}
{ }안에는 true일때 처리할 내용(해당 클래스 타입으로 down casting)작성

ex)
   if(c instanceof Sonata){
	 ((Sonata)c).moveSonata();
   } else if (c instanceof Avante) {
	 ((Avante)c).moveAvante();
   } else if (c instanceof Grandure){
	((Grandure)c).moveGrandure();
   }



3 . 다형성과 객체배열

  • 배열을 이용하면 여러 인스턴스를 하나의 레퍼런스 변수로 연속 처리할 수 있음
Car[] c = new Car[4]
c[0] = new Sonata
c[1] = new Avante
c[2] = new Sonata
c[3] = new Avante

  • 상위 클래스가 가지는 메소드를 오버라이딩한 메소드 호출 시 동적바인딩을 이용할 수 있음
for(int i = 0; 0 < c.length; i++){
    c [i].move();
}

◇ 실행 결과
소나타가 움직입니다
아반떼가 움직입니다
소나타가 움직입니다
아반떼가 움직입니다

  • 고유한 메소드를 동작시킬때 ClassCastException을 방지하기 위해서 instanceof 연산자를 이용
for(int i = 0; i < c.length; i++){
  if(c[i] instanceof Avante){
      ((Avante)c[i]).moveavante();
  } else if(c[i] instanceof Sonata){
      ((Sonata)c[i]).movesonata();
  } else {
   System.out.println("Sonata나 Avante가 아닙니다.");



4. 다형성과 매개변수

  • 매개변수 타입이 클래스 타입일 경우 해당 클래스 객체 뿐만 아니라 하위클래스 객체까지도 매개값으로 사용할 수 있다.
  • 묵시적 형변환으로 매개변수가 다양한 하위클래스 자료형을 받아줄 수 있음
메소드(클래스 레퍼런스변수) {
 레퍼런스.메소드();
}
Application app = new Application();
app.buy(new Sonata());
app.buy(new Avante());
app.buy(new Grandure());

public void buy(Car c){
 	c.pay();
}

  • 메소드에서 리턴되는 다양한 하위클래스 자료형을 받아줄 수 있음
Car car = app.randomCar();
car.move();

public Car randomCar(){
 	int random = (int) (Math.random()*2};
    return random == 0? new Sonata() : new Avante();
 }

반응형