[Java] 상속과 메모리 구조

김제현·2024년 1월 16일

Java

목록 보기
9/13
post-thumbnail

✔ 상속 관계

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

용어 정리

부모 클래스 (슈퍼 클래스) 상속을 통해 자신의 필드와 메서드를 다른 클래스에 제공하는 클래스
자식 클래스 (서브 클래스): 부모 클래스로부터 필드와 메서드를 상속받는 클래스

상속은 부모의 기능을 자식이 물려 받는 것이다. 따라서 자식이 부모의 기능을 물려 받아서 사용할 수 있다. 반대로 부모 클래스는 자식 클래스에 접근할 수 없다. 자식 클래스는 부모 클래스의 기능을 물려 받기 때문에 접근할 수 있지만, 그 반대는 아니다. 부모 코드를 보자! 자식에 대한 정보가 하나도 없다.

단일 상속

자바는 다중 상속을 지원하지 않기 때문에 extend 대상은 하나만 선택할 수 있다. 부모를 하나만 선택할 수 있다는 뜻이다. 하지만 부모가 또 다른 부모를 하나 가지는 것은 괜찮다.

왜냐하면 다중 상속을 사용하게 되면 두 부모가 동일한 메서드를 가지고 있으면 어떤 부모의 메서드를 사용할지 애매해지는 문제가 발생한다. -> 다이아몬드 문제라고 하는데, 이런 다중 상속 문제는 나중에 인터페이스 다중 구현을 통해 해결하면 된다.

상속과 메모리 구조

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

메서드 오버라이딩

package extends1.ex1;

public class Car {
    public void move() {
        System.out.println("차가 이동중입니다.");
    }
}
package extends1.ex1;

public class ElectricCar extends Car {
    @Override
    public void move() {
        System.out.println("전기차가 이동중입니다.");
    }
    public void charge() {
        System.out.println("충전중입니다.");
    }
}
  • 부모 타입의 기능을 자식에서는 다르게 재정의 하고 싶을 수 있다.
  • 예를 들어서 자동차의 경우 Car.move() 라는 기능이 있다. 이 기능을 사용하면 단순히 "차가 이동중입니다."라고 출력 한다. 전기차의 경우move() 를 호출한 경우에는 "전기차가 이동중입니다."라고 출력을 변경하고 싶을 때 위와 같이 활용한다.
  • 위와 같이 부모의 기능을 자식에서 재정의 하는 걸 메서드 오버라이딩이라고 한다.
  • @Override와 같이 에노테이션을 남기지 않아도 올바르게 작동은 되지만 실수를 방지하고 코드의 명확성을 위해 써주는 게 좋다.
  • final, static, private 는 오버라이딩이 불가하다. final은 말그대로 변경이 불가한 느낌인데 메서드 또한 final을 붙이게 될 경우 이 메서드는 끝났어같은 느낌이고 private 는 클래스 내에서만 접근할 수 있는 건데 될 수 있을리가 없고 static 은 오버라이딩은 찾고 그런게 다 인스턴스 레벨에서 이루어지는 데 static 은 애초에 클래스 레벨에서 이루어지기 때문에 될 수 없음.

오버로딩(Overloading)과 오버라이딩(Overriding)

  • 메서드 오버로딩: 메서드 이름이 같고 매개변수(파라미터)가 다른 메서드를 여러개 정의하는 것을 메서드 오버로딩(Overloading)이라 한다. 오버로딩은 번역하면 과적인데, 과하게 물건을 담았다는 뜻이다. 따라서 같은 이름 의 메서드를 여러개 정의했다고 이해하면 된다.

  • 메서드 오버라이딩: 메서드 오버라이딩은 하위 클래스에서 상위 클래스의 메서드를 재정의하는 과정을 의미한다. 따라서 상속 관계에서 사용한다. 부모의 기능을 자식이 다시 정의하는 것이다. 오버라이딩을 단순히 해석하면 무 언가를 넘어서 타는 것을 말한다. 자식의 새로운 기능이 부모의 기존 기능을 넘어 타서 기존 기능을 새로운 기능으 로 덮어버린다고 이해하면 된다. 오버라이딩을 우리말로 번역하면 무언가를 다시 정의한다고 해서 재정의라 한다. 상속 관계에서는 기존 기능을 다시 정의한다고 이해하면 된다. 실무에서는 메서드 오버라이딩, 메서드 재정의 둘 다 사용한다.

super - 부모 참조

  • 부모와 자식의 필드명이 같거나 메서드가 오버라이딩되어 있으면, 자식에서 부모의 필드나 메서드를 호출할 수 없다. 이때 super 키워드를 사용하면 부모를 참조할 수 있다. 이름 그대로 부모 클래스에 대한 참조를 나타낸다.
  • 쉽게 말해 this 는 자기 자신을 가리키는 것, super 는 부모를 가리키는 것을 의미한다.
  • 부모가 기본생성자가 아닌 생성자를 직접 정의했을 때 자식은 super을 사용해 부모의 생성자를 정의해야 한다.

참고

김영한 - 실전 자바

0개의 댓글