JAVA

[Java] 상속

songsua 2024. 10. 30. 23:12

상속은 기존 클래스의 필드와 메서드를 새로운 클래스에서 재사용하게 해준다.

이름 그대로 기존 클래스의 속성과 기능을 그대로 물려받은 것이다.

상속을 사용할려면, extends키워드를 사용하면 된다. 그리고 extends 대상은 하나만 선택할 수 있다.

 

용여 정리 

부모 클래스: 상속을 통해 자신의 필드와 메서드를 다른 클래스에 제공하는 클래스

자식 클래스: 부모 클래스로부터 필드와 메서드를 상속받는 클래스

 

package extend1.ex2;

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

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

}
package extend1.ex2;

public class GasCar extends Car{
    public void fillup() {
        System.out.println("fill up GasCar");
    }
}

 

extends 를 통해서Car을 상속 받을 수 있다

package extend1.ex2;

import extend1.ElectricCar;
import extend1.Gascar;

public class CarMain {
    public static void main(String[] args) {
        extend1.ex2.ElectricCar car= new extend1.ex2.ElectricCar();
        car.move();
        car.charge();

        GasCar gascar = new GasCar();
        gascar.move();
        gascar.fillup();
    }
}

 

 

결과값

차를 이동합니다.
충전합니다
차를 이동합니다.
fill up GasCar

 

단일 상속

참고로 자바는 다중 상속을 지원하지 않는다. 그래서 extend 대상은 하나만 선택할 수 있다.

부모를 하나만 선택할 수 있다는 뜻이다.

 

 

상속과 메모리 구조

메모리에는 자식과 부모 메서드를 두 개 다 올린다.

electricCar.charge()` 를 호출하면 참조값을 확인해서 `x001.charge()` 를 호출한다.

따라서 `x001` 을 찾아서 `charge()` 를 호출하면 되는 것이다. 그런데 상속 관계의 경우에는 내부에 부모와 자식이 모두 존재한다.

이때 부모인 `Car` 를 통해서 `charge()` 를 찾을지 아니면 `ElectricCar` 를 통해서 `charge()` 를 찾을지 선택해야 한다.

이때는 **호출하는 변수의 타입(클래스)을 기준으로 선택**한다. `

electricCar` 변수의 타입이 `ElectricCar` 이므로 인스턴스 내부에 같은 타입인 `ElectricCar` 를 통해서 `charge()` 를 호출한다

그런데 `ElectricCar` 에는 `move()` 메서드가 없다.

상속 관계에서는 자식 타입에 해당 기능이 없으면 부모 타입으 로 올라가서 찾는다.

이 경우 `ElectricCar` 의 부모인 `Car` 로 올라가서 `move()` 를 찾는다.

부모인 `Car` `move()` 가 있으므로 부모에 있는 `move()` 메서드를 호출한다.

 

 

상속과 접근 제어

`+` : public
`#` : protected `~` : default
`-` : private

 

 

  • **접근 제어자의 종류**
    `private` : 모든 외부 호출을 막는다.
    `default` (package-private): 같은 패키지안에서 호출은 허용한다.
    `protected` : 같은 패키지안에서 호출은 허용한다. 패키지가 달라도 상속 관계의 호출은 허용한다.
    `public` : 모든 외부 호출을 허용한다.

    순서대로 `private` 이 가장 많이 차단하고, `public` 이 가장 많이 허용한다. `private -> default -> protected -> public`
package extend1.access.parent;

public class Parent {
    public int publicValue;
    protected int protectedValue;
    int defaultValue;
    private int privateValue;

    public void publicMethod() {
        System.out.println("Parent.publicMethod");
    }

    public 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();
 }
}
package extend1.access.child;

import extend1.access.parent.Parent;

public class Child extends Parent {
    public void call() {
        //private int privateValue; 부모에서 선언한 변수값
        publicValue = 1;
        protectedValue = 1; //상속관계 or 같은 패키지.     protected int protectedValue;
       // defaultValue = 1;      int defaultValue; 로만 선언하면 다른 패키지에 있기 때문에 오류가 난다.
      //  privateValue = 1;    //     private int privateValue; 이기 때문에 접근 오류뜬다
        publicMethod();  // public. 이기 때문에 호출 가능
        protectedMethod();  // 상속 과 같은 패키지



        printParent();
        // public void printParent() 로 호출한다음 가져오기 때문에, 가능한다.
    }
}
package extend1.access;

import extend1.access.child.Child;

public class ExtendsAccessMain {
    public static void main(String[] args) {
        Child child = new Child();
        child.call();
    }
}

 

출력값

Parent.publicMethod
Parent.protectedMethod
==Parent 메서드안==
publicValue: 1
protectedValue: 1
defaultValue: 0
privateValue: 0
Parent.defaultMethod
Parent.privateMethod

parent 와 child  두 부분으로 나눠서 저장을 하며, 부모 입장에서 보면 외부에서 호출된 것이다.

 

 

'JAVA' 카테고리의 다른 글

[Java] 다형성  (0) 2024.11.01
[Java] 상속 문제와 풀이  (0) 2024.11.01
[Java] Static 메서드1  (1) 2024.10.27
[Java] Static  (0) 2024.10.27
[Java] 메모리구조  (2) 2024.10.27