[java]상속관계에서 객체생성 & Override

송어·2023년 11월 13일

동작측면에서의 클래스 설계

클래스를 수평적 구조로 설계할 시 메서드 측면에서도 중복이 발생할 수 있다.

public class Dog {
	public void eat() {
    	System.out,println("개처럼 먹다");
    }
}
public class Cat {
	public void eat() {
    	System.out,println("고양이처럼 먹다");
    }
    public void eyeLight() {
    	System.out.println("밤에 눈에서 빛이 난다");
    }
}

Dog class의 eat()메서드와 Cat class의 eat()메서드에서 중복이 발생한다.

public class AnimalTest {
	public static void main(String[] args) {
    	Dog d = new Dog();
        d.eat();
        
        Cat c = new Cat();
        c.eat();
        c.night();
    }
}

중복을 해결하기 위해 상속을 활용해 수직적 구조로 설계해보자

public class Animal {
	public void eat() {
    	System.out,println("먹다");
    }
}
public class Dog extends Animal {
	
}
----------------------------------
public class Cat {
    public void eyeLight() {
    	System.out.println("밤에 눈에서 빛이 난다");
    }
}
public class AnimalTest {
	public static void main(String[] args) {
    	Dog d = new Dog();
        d.eat();
        
        Cat c = new Cat();
        c.eat();
        c.night();
    }
}

상속을 통해 메서드 중복은 해결되었지만, 코드의 추상성이 증대되었다.

상속관계에서 객체생성 방법

상속관계에서 객체생성 시 부모가 자식을 가리키는 upcasting방식을 사용해 객체를 생성하는 것이 바람직하다.

  • Upcasting(업캐스팅) : 부모가 자식을 가리키는 객체생성방법
    하지만 upcasting을 사용해 객체를 생성하게 되면 자식타입의 멤버에는 접근이 불가능하다.
    업캐스팅 방식으로 객체를 생성하되 자식타입의 멤버 메서드에도 접근이 가능하도록 하려면 부모의 메서드를 자식 메서드에서 재정의하는 Override(오버라이딩)를 활용해야한다.

동적 바인딩이란?

실행 시점에서 사용될(호출될)메서드가 결정(연결)되는 바인딩

정적 바인딩의 반대 개념으로 컴파일 시점에 호출될 메서드가 결정되는 게 아닌 메서드 실행 시점에 사용될 메서드가 결정된다. 메서드 오버라이딩의 경우, 실행 시점에 오버라이딩한 메서드를 찾아서 실행을 결정한다.

Override - 메서드의 재정의

메서드의 재정의(Override)는 왜 필요할까? 상속관계에서 자식클래스이 부모클래스의 메서드를 상속받아 자유롭게 사용할 수 있지만, 그대로 상속받아 사용하기에는 자식클래스에게 맞지 않을 수 있다. 이 때 상속받은 메서드를 자식클래스에 맞게 재정의(Override)하는 것이다.

오버라이딩을 통해 업캐스팅을 통해 객체생성을 한 경우에도 자식클래스의 메서드에 접근할 수 있게 된다.

public class Dog extends Animal {
    @Override
    public void eat() { // 메서드 오버라이드
        System.out.println(super.getClass().getSimpleName() + " : " + "개처럼 먹다");
    }
}

------------------------------------------

public class Cat extends Animal {
    @Override
    public void eat() { // 메서드 오버라이드
        System.out.println(super.getClass().getSimpleName() + " : " + "고양이처럼 먹다");
    }
}
public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // upcasting
        Animal animal2 = new Cat();
        animal1.eat(); // 동물처럼먹다 -> 개처럼먹다 (오버라이드됨) : 실행시점에 실행 메서드 결정
        animal2.eat();
    }
}
<esult>
Dog : 개처럼 먹다
Cat : 고양이처럼 먹다

0개의 댓글