Java

[인프런] 상속

sejin2 2024. 5. 27. 13:29
public class ElectricCar {

    public void move() {
        System.out.println("차를 이동합니다.");
    }

    public void charge() {
        System.out.println("충전합니다.");
    }
}
public class GasCar {

    public void move() {
        System.out.println("차를 이동합니다.");
    }

    public void fillUp() {
        System.out.println("기름을 주유합니다.");
    }
}
public class CarMain {
    public static void main(String[] args) {
        ElectricCar electricCar = new ElectricCar();
        electricCar.move();
        electricCar.charge();

        GasCar gasCar = new GasCar();
        gasCar.move();
        gasCar.fillUp();
    }
}

전기차와 가솔린차를 만들었고 해당 클래스에는 각각의 기능이 있다. 
전기차와 가솔린차는 자동차의 더 구체적인 개념이다. 반대로 자동차는 전기차와 가솔린차를 포함하는 추상적인 개념이다. 두 클래스에는 move( ) 라는 공통 개념이 있다.
전기차든 가솔린 차든 주유하는 방식이 다른 것이지 이동하는 것은 똑같다. 이런 경우에 상속 관계를 사용하는 것이 효과적이다.

상속 관계

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

  • 부모 클래스 ( 슈퍼 클래스 ) : 상속을 통해 자신의 필드와 메서드를 다른 클래스에 제공하는 클래스
  • 자식 클래스 ( 서브 클래스 ) : 부모 클래스로부터 필드와 메서드를 상속받는 클래스
public class Car {
    public void move() {
        System.out.println("차를 이동합니다.");
    }
}
public class ElectricCar extends Car{
    public void charge() {
        System.out.println("충전합니다.");
    }
}

public class GasCar extends Car{
    public void fillUp() {
        System.out.println("기름을 주유합니다.");
    }
}
public class CarMain {
    public static void main(String[] args) {
        ElectricCar electricCar = new ElectricCar();
        electricCar.move();
        electricCar.charge();

        GasCar gasCar = new GasCar();
        gasCar.move();
        gasCar.fillUp();
    }
}

전기차와 가솔린차가 Car를 상속 받은 덕분에 electricCar.move( ) , gasCar.move( )를 사용할 수 있다. 
상속은 부모의 기능을 자식이 물려받는 것으로 자식이 부모의 기능을 사용할 수 있다. 반대로 부모 클래스는 자식 클래스에 접근할 수 없다. 부모 코드는 자식에 대한 정보가 하나도 없다.

단일 상속

자바는 다중 상속을 지원하지 않는다. 따라서 extend 대상은 하나만 선택할 수 있다. 즉, 부모를 하나만 선택할 수 있다는 의미이다. 부모가 또 다른 부모를 하나 가지는 것은 가능하다. 
다중 상속을 하게 되면 다이아몬드 문제가 발생한다. ( 어떤 부모의 메서드를 호출해야할지 알수 없음 ) 따라서 자바에서는 다중 상속을 허용하지 않고, 인터페이스의 다중 구현을 허용해 이러한 문제를 피한다. 

상속과 메모리 구조 - 중요★

상속 관계를 객체로 생성할 때 메모리 구조를 확인해본다.

ElectricCar electricCar = new ElectricCar();

new ElectricCar(  )를 호출하면 ElectricCar 뿐 만 아니라 상속관계에 있는 Car까지 포함해서 인스턴스를 생성한다.
참조값은 x001로 하나이지만 그 안에서는 Car, ElectricCar라는 두 가지 클래스 정보가 공존한다.
상속이라고 해서 단순히 부모의 필드와 메서드만 물려받는게 아니라 부모 클래스도 함께 포함해서 생성된다.
외부에서 볼 때는 하나의 인스턴스를 생성하는 것 같지만 내부에서는 부모와 자식이 모두 생성되고 공간도 구분된다.

electricCar.charge();

electricCar.charge()를 호출하면 참조값을 확인해서 x001.charge( ) 를 호출한다.따라서 x001을 찾아서 charge(  )를 호출하면 된다. 상속 관계의 경우 내부에 부모와 자식이 모두 존재하므로 부모인 Car를 통해서 charge(  )를 찾을지 아니면 ElectricCar를 통해서 charge( )를 찾을지 선택해야 한다.
이때는 호출하는 변수의 타입(클래스)을 기준으로 선택한다. electricCar 변수의 타입이 ElectricCar이므로 인스턴스 내부에 같은 타입인 ElectricCar를 통해 charge( )를 호출한다. 

만약 부모에서도 해당 기능을 찾지 못하면 더 상위 부모에서 필요한 기능을 찾는다. 부모에 부모로 계속 올라가면서 필드나 메서드를 찾는데, 계속 찾아도 찾지 못하면 컴파일 오류가 발생한다.

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

 

 

 

공부 내용: [인프런] 김영한의 실전 자바 - 기본편

'Java' 카테고리의 다른 글

[인프런] 상속과 접근 제어  (0) 2024.05.27
[인프런] 상속과 메서드 오버라이딩  (0) 2024.05.27
[인프런] final 변수와 상수  (0) 2024.05.27
[인프런] static 메서드  (0) 2024.05.26
[인프런] static 변수  (0) 2024.05.26