JAVA

[JAVA]오버라이드(Override)

당고개 2023. 10. 23. 23:13

오버라이드의 의미는 더 우선시한다는 의미로 부모 클래스에 정의된 내용보다 자식 클래스에서 정의한 내용을 더 우선시합니다. 메서드의 내용을 재정의하는 것 즉 행위의 내용을 재정의하는 것과 같습니다.

오버라이딩

메서드를 오버라이딩하는 방법은 다음과 같습니다. 부모의 메서드와 동일한 메서드를 자식 클래스에서 재정의 하면 됩니다.

public class Dog {
    protected String color;

    public void bite() {
        System.out.println("앙!");
    }

    public void bark() {
        System.out.println("왈왈!");
    }
}
public class Jindodog extends Dog {

    // 부모의 메서드를 재정의 했다.
    public void bite() {
        System.out.println("와작");
    }

    // 부모의 메서드를 재정의 했다.
    public void bark() {
        System.out.println("컹컹!");
    }
}

다형성과 메서드 오버라이드의 관계

Dog dog1 = new Dog();
dog1.bite(); // "앙"
dog1.bark(); // "왈왈!"

Dog dog2 = new Jindodog();
dog2.bite(); // "와작"
dog2.bark(); // "컹컹!"

자식 클래스에서 오버라이드 된 메서드가 존재하는 경우 생성된 인스턴스에 따라 호출하는 내용이 달라집니다.

super.메서드명(매개변수)

자식 클래스에서 부모 메서드를 재정의 했을 때, 부모의 메서드를 호출하는 방법은 super.메서드명(매개변수)을 사용하면 됩니다.

public class Dog {
    protected String color;

    public void bite() {
        System.out.println("앙!");
    }

    public void bark() {
        System.out.println("왈왈!");
    }
}
public class Jindodog extends Dog {

    // 부모의 메서드를 재정의 했다.
    public void bite() {
        // bite()를 호출하면 스코프에 의해 
        // 자식 클래스의 bite() 메서드를 호출하는 상황이 발생한다.
        // bite();

        // 부모 메서드를 호출하는 방법은 super 키워드를 사용하면 된다.
        super.bite(); 
        System.out.println("와작");
    }

    // 부모의 메서드를 재정의 했다.
    public void bark() {
        System.out.println("컹컹!");
    }

}

bite() 를 호출하면 스코프에 의해 자식 클래스의 bite() 메서드를 호출하는 상황이 발생합니다. 스코프 내에서 가장 가깝게  정의된 bite() 메서드는 자식 클래스의 bite() 메서드이기 때문입니다. 자식 클래스에서 부모 클래스에 정의된 bite() 를 호출하려면 super 키워드를 이용하여 super.bite() 를 호출하면 됩니다.

접근제어 지시자와 오버라이드의 관계

public class Dog {
    protected String color;

    private void eat() {
        System.out.println("먹는다");
    }

    void bite() {
        System.out.println("앙!");
    }

    protected void bark() {
        System.out.println("왈왈!");
    }
}
public class Jindodog extends Dog {

    // 오버라이드가 아닌 Jindodog 클래스에서 사용할 새로운 메서드
    private void eat() {
        System.out.println("잘먹는다");
    }

    public void bite() {
        System.out.println("와작");
    }

    // 부모의 메서드를 재정의 했다.
    public void bark() {
        System.out.println("컹컹!");
    }

}

부모 클래스에서 private 지시자로 선언된 클래스는 자식 클래스에서 접근할 수도 없고 오버라이드 할 수도 없습니다.

부모 클래스의 메서드를 오버라이드시 접근제어 지시자는 이미 부모 클래스에서 선언된 접근제어 지시자보다 더 공개된 범위의 접근제어 지시자로만 변경이 가능합니다.

부모 default 메서드 →  자식 default, protected, public 메서드
부모 protected 메서드   자식 protected, public 메서드
이런 특성은 다형성을 유지하도록 만듭니다.

변수도 오버라이드가 가능한가?

메서드만 오버라이드 할 수 있습니다. 변수는 오버라이드 할 수 없습니다.

public class Dog {
    public String color = "검정";
}

public class Jindodog extends Dog {
    public String color = "베이지";

    public String getColor() {
        return color;
    }

    public String getParentColor() {
        return super.color;
    }
}
Dog dog = new Jindodog();

System.out.println(dog.color); 
// 검정

변수가 오버라이드 되었다면 재정의한 "베이지"라는 문자열이 출력되어야 합니다.
그러나 실제로는 '검정'이라는 문자열이 출력됩니다. '베이지'라는 문자열을 출력하려면 인스턴스와 동일한 참조 자료형으로 선언해야합니다.

Jindodog dog = new Jindodog();

System.out.println(dog.color); 
// 베이지

Jindodog 클래스에 color 변수가 정의 되어있는 상태이고 Jindodog 클래스 내부에서 부모의 color 변수에 접근하려면 어떻게 해야 할까요?
방법은 super 키워드를 이용하여 부모의 변수에 접근할 수 있습니다.

super.color;

 

 

 

출처 : https://www.codelatte.io/courses/java_programming_basic/3LKOR35EIWF3XTK2

'JAVA' 카테고리의 다른 글

[JAVA]추상클래스와 인터페이스  (0) 2023.10.25
[JAVA]추상화  (0) 2023.10.24
[JAVA]다형성  (0) 2023.10.19
[JAVA]상속과 생성자  (0) 2023.10.18
[JAVA]상속  (0) 2023.09.21