JAVA/Bootcamp 자바

Override재정의, Upcasting, 동적바인딩

whyHbr 2024. 2. 28. 15:31
728x90
반응형

클래스의 행위(동적) 정보에 맞춰 클래스를 설계 (상속) 하는 방법에 대해 알아보자

 

수평적 구조는 중복 발생, 유지보수의 여러움, 확장성 떨어짐 과 같은 많은 문제가 있다.

->그래서 수직적 구조를 쓴다. 부모가 중복 부분을 만들고, 자식들은 상속 받으면 된다.

 

부모와 자식을 연결해 부모를 이용, 자식을 동작시킬 수 있는 원리로 클래스를 설계 해야한다.

자식 클래스를 숨기고 바깥쪽에 있는 부모로 자식을 동작 시킬 수 있는 방법 -> 상속

상속 구조를 왜 쓸까?

- 코드 중복 최소화, 메서드 재활용

 

부모 클래스를 통제하면 자식들도 통제된다. 부모에 의해 자식들의 동작 방법이 달라진다.

 

 

Dog 클래스 사용 시 만든 사람은 동작구조를 알지만 사용하는 사람은 모른다.

왜? 소스코드를 노출시키지 않기 때문 - 다른 클래스에 의해 Dog 을 동작시킨다

Dog과 동작 시키는 클래스를 세트로 만들 필요가 있다.

 

어떤 클래스가 중요해 노출시키고 싶지 않다면, 리모콘 같은 클래스가 필요하다

TV = 자식, 리모콘 = 부모

부모가 명령하고 자식은 실행한다.

Tv안 구성 요소를 알 필요는 없다. 리모콘 사용 방법만 알면 된다.

?class 가 Animal class 이다. Animal class를 구동하면 Dog을 이용할 수 있게 해야한다.

 

 

 

어떻게 구동하지?

Animal과 Dog은 상속관계이다. 자식을 노출시키지 않고 부모를 사용해 자식 이용이 가능하다.

Dog을 다른 사람에게 주고싶다? -> animal과 상속관계를 해 배포해야한다. 

 

Dog을 쓰려면 객체 생성을 해야한다.

Dog d = new Dog(); //이것은 바람직하지 않다. dog의 동작방식을 모를 때 d.를 한다면 dog에 어떤 메서드가 있는지 모른다.

 

그래서 Animal을 써야한다. 이것을 Upcasting 라고 한다. 

부모를 통해 자식을 구동하는 방법이다.

객체 생성은 자식이 하고 (Dog), 부모가 받는다(Animal)

Animal ani = new Dog();

부모는 큰 타입이고 자식은 작은 타입이기 때문에 받을 수 있다.  상속관계이기 때문에 가능하다.

 

dog이 animal을 상속 받으면 dog+ animal 사용 가능하다.

ani는 부모 클래스의 eat()을 사용할 수 있다.

업캐스팅으로 만든 것은 부모의 eat에는 접근 가능하나, 자식의 eat에는 접근이 불가능하다.

업캐스팅을 부모 타입으로 받기 때문에 ani는 부모 메모리에만 접근 할 수 있다.

 

업캐스팅으로 만들어진 것은 어떻게 자식 메서드를 쓸 수 있을까?

 

 상속 체이닝과 super

상속 체이닝? 상속이 되어 온 족보.. 최상위 클래스인 Object class까지 올라간다.

 

자식 생성 전, 부모가 생성 되어야한다 super()을 통해 부모 먼저 생성시킨다.

자식은 부모의부모의부모의.. 것까지 쓸 수 있다.

 

부모, 자식에게 eat() 이 있다면

부모가 가진 것을 자식이 물려받아 자식에게 맞게 재정의를 해야한다 

-> Override

 

ani는 재정의 된 것이 있는지 둘러본다. 자식이 재정의를 했다면 자식의 eat()이 실행된다 

부모의 eat()을 컴파일 했는데 자식의 eat()이 구동된다. 실행해봐야 알 수 있다

-> 이것을 동적바인딩 이라고 한다.

컴파일 시점에선 모른다. 런타임 즉, 실행해봐야 누구의 것인지 안다.

 

 

super();는 생성자 문장의 가장 첫 문장에서 실행해야 한다 (= first statement) 

public class Dog extends Animal{
   
public Dog(){
       
int a=10; //수행문.
       
super(); //new Animal() 호출됨.
   
}

이러면 안된다는 소리. int a=10;은 super뒤로 와야한다.

 

 

 

메서드 재정의override란

부모에게 받은 것이 자식에게 부적합하다. -> 부모의 eat()을 재정의한다. 나에게 맞게 수선한다.

이것이 재정의 override

 

POV:

1. 컴파일 시점엔 부모의 것

2. 실행 되면 자식의 것, 

   jvm이 부모의 eat을 찾아간다. 재정의가 되어있다면 자식의 eat을 구동한다. 

 

 Animal을 가지고 Dog의 eat을 구동시킨다 -> 동적바인딩

실행 시점에서 사용될 메서드가 결정된다. 누구의 eat인지 실행 전까지는 모른다. 

 

 

Dog, cat 클래스의 eat 을 재정의 한다.

public void eat(){ //override,재정의
   
System.out.println("dog: eat");
}

 

public void eat(){
    System.
out.println("cat: eat");
}

 

public class OverrideTest {
   
public static void main(String[] args) {
        Animal ani =
new Dog(); //upcasting
        //
?하지: dog class파일만 있을 , dog 가지고 구동하기엔 무리
        // animal
이라는 클래스가 dog 상속관계일때,
       
ani.eat(); //컴파일전 animal , 실행 Dog 것이 -> 동적바인딩
       
ani =new Cat();
       
ani.eat();

   
}
}

업캐스팅 : Animal ani = new Dog(); 

부모를 통해 자식을 구동하고 싶을 때,

 

 

public void eat(){
    System.out.println("동물 : eat");
}

부모 클래스도  eat이라는 메서드가 있지만, 자식의 eat메서드가 실행된다. 

왜? 자식이 재정의, override 해놨기 때문에. 

728x90

'JAVA > Bootcamp 자바' 카테고리의 다른 글

자바 - 다형성  (0) 2024.02.29
Downcasting, 객체형변환  (0) 2024.02.28
부모, 자식, 상속, protected, extends  (0) 2024.02.27
class, object, instance  (0) 2024.02.26
JVM의 메모리영역, 객체 생성과 static  (1) 2024.02.26