Java - 9. Inheritance

Mingi Shin·2023년 11월 1일
0

java

목록 보기
9/10
post-thumbnail

상속은 말 그대로 자식 클래스가 부모를 상속받아 부모의 필드와 메서드를 사용 가능하게 하는 것이다. 부모 클래스는 superclass, base class라고도 하며, 자식 클래스는 subclass, derived class라고도 한다.

상속은 기존의 코드를 재사용해 개발 효율을 높이게 해준다.

public class Car extends Vehicle
{
  // class contents
}

자바에서 상속은 다음과 같은 문법으로 한다. Car class가 Vehicle class를 상속받고 있다.

상속이더라도 부모의 어떤 필드나 메서드가 private으로 존재한다면 자식은 해당 필드나 메서드를 물려받을 수 없다. public의 경우 그것이 가능하지만 이는 캡슐화 원칙을 위배한다. 이러한 상황에서 protected를 사용하게 된다. protected는 자식 클래스가 사용할 수 있고 public보다 더 많은 캡슐화를 제공한다.


Single Inheritance

자바는 다중 상속을 지원하지 않는다. 단일 상속을 지원하며 extends 뒤에는 하나의 클래스가 올 수 있다. 그림은 B가 A를 상속받고 있다.


Multi-level Inheritance

그림은 다단계로 B가 A를 상속받고 C를 A가 상속 받아 C는 B와 A의 필드, 메서드를 사용할 수 있다.


Hierarchical Inheritance

A를 B, C가 상속받는 것처럼 계층적으로 상속을 이끌어 낼 수도 있다.


Multiple Inheritance

자바는 "클래스에서" 다중 상속을 지원하지 않는다. 하지만, 인터페이스에서는 다중 상속이 가능하다.

interface A1
{
  public void input();
}

interface A2
{
  public void get();
}

interface AA extends A1, A2
{
  public void result();
}

class Result implements AA
{
  int n1, n2;
  public void input() {
    Scanner obj=new Scanner (System.in);
    n1= obj.nextInt();
  }
  public void get() {
    Scanner obj=new Scanner (System.in);
    n2= obj.nextInt();
  }
  public void result(){
    System.out. println(n1+n2);
  }
}

public class Multiple {
  public static void main(String[] args) {
    Result obj1= new Result();
    obj1.input();
    obj1.get();
    obj1.result();
  }
}

AA는 A1, A2를 다중으로 상속 받고 있다. AA 구현체인 Result 클래스는 A1의 input(), A2의 get()를 정의하고 있다.

다른 방법으로 한 클래스가 다른 한 클래스를 상속받고 인터페이스를 구현하는 형태로 다중 상속을 달성할 수도 있다.


Hibrid Inheritance

하이브리드 상속은 여러 상속 타입을 혼합해 조합하는 것이다. 어떤 클래스가 여러 추상 클래스를 상속받고 그 클래스를 계층적으로 다른 클래스들이 상속받는 방식이 그 예시다. 오른쪽 그림은 B, C가 A를 계층적으로 단일 상속받고 그 둘을 D가 다중 상속받고 있는 형태인데 자바에서 허용되지는 않는다.


super

모든 클래스는 생성자가 있다. 그렇지만 상속 시에 생성자는 public임에도 상속 대상에서 제외된다. 만약, 자식을 통해 부모를 설정하고 싶다면, super 참조를 사용한다.

super는 부모 클래스를 참조하는 데에 사용되며 가끔 부모의 생성자를 호출하는 목적으로 쓰인다.

class One{
  int a=10;
}
class Two extends One{
  int a=100;
  
  void display(){
    System.out.println("Child Class:"+a);
    System.out.println("Parent Class:"+super.a);
  }
}

위는 부모의 변수와 자식의 변수가 같아 모호한 경우 super를 쓰고 있다.

class Upper{

  void message(){
    System.out.println("This is Upper class");
  }
}

class Lower extends Upper {

  void message(){
    System.out.println("This is Lower class");
  }
  // Note that display() is only in Lower class
  void display(){
    // will invoke or call current class message() method
    message();
    // will invoke or call parent class message() method
    super.message();
  }
}

메서드 경우 역시 마찬가지로 모호성을 해소하기 위해 super가 쓰인다.

class Person {
  Person(){
    System.out.println("Person class Constructor");
  }
}
class Officer extends Person {

Officer() {
    // invoke or call parent class constructor
    //this is optional
    super();
    System.out.println("Officer class Constructor");
  }
}

3번째로 super는 부모 클래스의 생성자에 접근하는 데에 사용된다. 자식 클래스 생성자의 첫 번째 줄은 super 참조를 해 부모 클래스의 생성자를 호출해야 한다. 자식 클래스는 부모의 필드, 메서드를 물려받기 때문에 당연히 부모 클래스의 초기화를 먼저 진행해줘야 하기 때문이다.

class First {

int n1, n2;
First(int a, int b) {
  n1=a;
  n2=b;
  System.out.println(n1);
  System.out.println(n2);
  }
}

class Second extends First {

  Second() { //constructor
    super(10, 20);
  }
}

물론 자식의 디폴트 생성자는 부모의 파라미터 생성자를 호출할 수도 있다.

profile
@abcganada123 / git:ABCganada

0개의 댓글

관련 채용 정보