hayu's 개발 일지

[TIL]240710 상속 본문

기술/java

[TIL]240710 상속

hayu00 2024. 7. 10. 21:21

공부한 내용

상속

  • 상속은 객체 지향 프로그래밍의 핵심 요소 중 하나로, 기존 클래스의 필드와 새로운 클래스에서 재사용하게 해준다.
  • 이름 그대로 기존 클래스의 속성과 기능을 그대로 물려받는 것이다.
  • 상속을 사용하려면 extends 키워드를 사용하면 된다.
  • 그리고 extends 대상은 하나만 선택할 수 있다.

단일 상속

  • 자바는 다중 상속을 지원하지 않는다. 그래서 extends 대상을 하나만 선택할 수 있다. 부모를 하나만 선택할 수 있다는 뜻이다. 물론 부모가 또 다른 부모를 하나 가지는 것은 괜찮다.

상속과 메모리 구조

  • 상속 관계의 객체를 생성하면 그 내부에는 부모와 자식이 모두 생성된다.
  • 상속 관계의 객체를 호출할 때, 대상 타입을 정해야 한다. 이 때 호출자의 타입을 통해 대상 타입을 찾는다.
  • 현재 타입에서 기능을 찾지 못하면 상위 부모 타입으로 기능을 찾아서 실행한다. 기능을 찾지 못하면 컴파일 오류가 발생한다.

상속과 메서드 오버라이딩

  • 부모 타입의 기능을 자식에서는 다르게 재정의하고 싶을 수 있다.
  • 부모에게서 상속 받은 기능을 자식이 재정의하는 것을 메서드 오버라이딩(Overriding)이라 한다.

→ 메서드 이름은 같지만 새로운 기능을 사용하고 싶을 때 새로운 메서드를 만들어 부모의 기능을 자식이 재정의하는 것을 메서드 오버라이딩이라 한다.

@Override

  • @ 이 붙은 부분을 애노테이션이라 한다. 애노테이션은 주석과 비슷한데, 프로그램이 읽을 수 있는 특별한 주석같은 개념이다.
  • 이 애노테이션은 상위 클래스의 메서드를 오버라이드하는 것임을 나타낸다.
  • 이름 그대로 오버라이딩한 메서드 위에 이 애노테이션을 붙여야 한다.
  • 컴파일러는 이 애노테이션을 보고 메서드가 정확히 오버라이드 되었는지 확인한다. 오버라이딩 조건을 만족시키지 않으면 컴파일 에러를 발생시킨다. 따라서 실수로 오버라이딩을 못하는 경우를 방지해준다.
  • 참고로 이 기능은 필수는 아니지만 코드의 명확성을 위해 붙여주는 것이 좋다.

메서드 오버라이딩 조건

  • 메서드 이름: 메서드 이름이 같아야 한다.
  • 메서드 매개변수(파라미터): 매개변수(파라미터) 타입, 순서, 개수가 같아야 한다.
  • 반환 타입: 반환 타입이 같아야 한다. 단 반환 타입이 하위 클래스 타입일 수 있다.
  • 접근 제어자: 오버라이딩 메서드의 접근 제어자는 상위 클래스의 메서드보다 더 제한적이어서는 안된다. 예를 들어, 상위 클래스의 메서드가 protected 로 선언되어 있으면 하위 클래스에서 이를 public 또는protected 로 오버라이드할 수 있지만, private 또는 default 로 오버라이드 할 수 없다.
  • 예외: 오버라이딩 메서드는 상위 클래스의 메서드보다 더 많은 체크 예외를 throws 로 선언할 수 없다. 하지만 더 적거나 같은 수의 예외, 또는 하위 타입의 예외는 선언할 수 있다. 예외를 학습해야 이해할 수 있다.

상속과 접근 제어

접근 제어자의 종류

  • private : 모든 외부 호출을 막는다.
  • default (package-private): 같은 패키지안에서 호출은 허용한다.
  • protected : 같은 패키지안에서 호출은 허용한다. 패키지가 달라도 상속 관계의 호출은 허용한다.
  • public : 모든 외부 호출을 허용한다.
  • 순서대로 private 이 가장 많이 차단하고, public 이 가장 많이 허용한다.
  • private -> default -> protected -> public
package extends1.access.parent;
public class Parent {
    public int publicValue;
    protected int protectedValue;
    int defaultValue;
    private int privateValue;
    public void publicMethod() {
        System.out.println("Parent.publicMethod");
    }
    protected void protectedMethod() {
        System.out.println("Parent.protectedMethod");
    }
    void defaultMethod() {
        System.out.println("Parent.defaultMethod");
    }
    private void privateMethod() {
        System.out.println("Parent.privateMethod");
    }
    public void printParent() {
        System.out.println("==Parent 메서드 안==");
        System.out.println("publicValue = " + publicValue);
        System.out.println("protectedValue = " + protectedValue);
        System.out.println("defaultValue = " + defaultValue); //부모 메서드 안에서 접
        근 가능
        System.out.println("privateValue = " + privateValue); //부모 메서드 안에서 접
        근 가능
        //부모 메서드 안에서 모두 접근 가능
        defaultMethod();
        privateMethod();
    }
}

  • 부모 클래스인 Parent 에는 public , protected , default , private 과 같은 모든 접근 제어자가 필드와 메서드에 모두 존재한다.
  • publicValue = 1 : 부모의 public 필드에 접근한다. public 이므로 접근할 수 있다.
  • protectedValue = 1 : 부모의 protected 필드에 접근한다. 자식과 부모는 다른 패키지이지만, 상속 관계이므로 접근할 수 있다.
  • defaultValue = 1 : 부모의 default 필드에 접근한다. 자식과 부모가 다른 패키지이므로 접근할 수 없다.
  • privateValue = 1 : 부모의 private 필드에 접근한다. private 은 모든 외부 접근을 막으므로 자식이라도 호출할 수 없다.

super - 부모 참조

  • 부모와 자식의 필드명이 같거나 메서드가 오버라이딩 되어 있으면, 자식에서 부모의 필드가 메서드를 호출할 수 없다.
  • 이때, super 키워드를 사용하면 부모를 참조할 수 있다.
  • super는 이름 그대로 부모 클래스에 대한 참조를 나타낸다.

super 생성자

  • 상속 관계의 인스턴스를 생성하면 결국 메모리 내부에는 자식과 부모 클래스가 각각 다 만들어진다.
  • 상속 관계에서 부모의 생성자를 호출할 때는 super(...) 를 사용하면 된다.
  • 상속 관계의 생성자 호출은 결과적으로 부모에서 자식 순서로 실행된다. 따라서 부모의 데이터를 먼저 초기화하고 그 다음에 자식의 데이터를 초기화한다.
  • 상속 관계에서 자식 클래스의 생성자 첫줄에 반드시 super(...) 를 호출해야 한다. 단 기본 생성자 ( super() )인 경우 생략할 수 있다.

 

 

'기술 > java' 카테고리의 다른 글

[TIL]240712 추상 클래스(Abstract)  (0) 2024.07.12
[TIL]240711 자바 코드 구조 이해  (0) 2024.07.11
[TIL]240706 final  (0) 2024.07.06
[TIL]240705 static  (0) 2024.07.05
[TIL]240704 자바 메모리 구조  (0) 2024.07.04