경계의 경계

자바의 상속 본문

Java

자바의 상속

gigyesik 2024. 2. 4. 13:52

상속 (Inheritance) 이란 무엇인가

상속은 자바의 객체 지향 프로그래밍의 중요한 한 축을 담당하는 개념이다.

이미 구현되어 있는 클래스의 필드와 메서드들을 재사용하기 위해 새로운 클래스를 만드는 것으로,

상속받은 클래스에서 새로운 필드와 메서드를 정의하는 것도 가능하다.

상속은 왜 사용하는가

  • 코드 재사용성 (Code Reuseability) : 부모 클래스의 코드는 모든 자식 클래스에서 공통적으로 사용할 수 있다.
  • 메서드 오버라이딩 (Method Overriding) : 상속을 통해서만 구현할 수 있는 메서드 동작 덮어쓰기이다. 런타임에서 다형성 (Polymorphism) 을 구현할 수 있다.
  • 추상화 (Absatraction) : 자식 클래스에서는 부모 클래스의 내부 구현보다는 외부적 기능에만 집중할 수 있게 해준다.

용어 정리

  • 클래스 (Class) : 변수 (Variable) 와 메서드 (Method) 를 갖는 객체 생성을 위한 설계도
  • 부모 클래스 (Super Class / Parent Class) : 상속을 당하는 클래스
  • 자식 클래스 (Sub Class / Child Class) : 부모 클래스를 상속하는 클래스

상속의 기본적인 구현

class ChildClass extends ParentClass {
    // fields
    // methods
}
public class ParentClass {
    // 필드
    public int code;
    public int commit;
    // 부모 클래스에서 초기화한 변수
    int a = 10;

    // 생성자
    public ParentClass(int code, int commit) {
        this.code = code;
        this.commit = commit;
    }

    public void coding(int line) {
        code += line;
    }

    public void commit(int code) {
        commit += code;
    }

    public String print() {
        return "now code is " + code + " and commit is " + commit;
    }
}

public class ChildClass extends ParentClass {
    // 자식 클래스에서 새로 정의한 필드
    public int merge;
    int b = 20;

    public ChildClass(int code, int commit, int merge) {
        // 부모 클래스의 필드 super 키워드로 주입
        super(code, commit);
        this.merge = merge;
    }

    public void merge(int code) {
        merge += code;
    }

    @Override
    public String print() {
        return super.print() + " and now merge is " + merge;
    }

    // driver class method
    public static void main(String[] args) {
        ChildClass cc = new ChildClass(0,0, 0);
        System.out.println(cc.print()); // now code is 0 and commit is 0 and now merge is 0
        cc.coding(10);
        cc.commit(5);
        cc.merge(1);
        System.out.println(cc.print()); // now code is 10 and commit is 5 and now merge is 1
        System.out.println(cc.a + " " + cc.b); // 10 20
    }
}

상속의 유형

단일 상속 (Single Inheritance)

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

class Child extends Parent {
    public void printChild() {
        System.out.println("Child");
    }
}

Child c =  new Child();
c.printParnet(); // Parent;
c.printChild(); // Child;

다중 상속 (Multilevel Inheritance)

class Grandparent {
    public void printGrandparent() {
        System.out.println("Grandparent");
    }
}

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

class Child extends Parent {
    public void printChild() {
        System.out.println("Child");
    }
}

Child c =  new Child();
c.printGrandParent(); // Grandparent
c.printParnet(); // Parent
c.printChild(); // Child

계층적 상속 (Hierarchical Inheritance)

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

class Child1 extends Parent {
    public void printChild() {
        System.out.println("Child1");
    }
}

class Child2 extends Parent {
    public void printChild() {
        System.out.println("Child2");
    }
}

Child1 c1 = new Child1();
Child2 c2 = new Child2();

c1.printParent(); // Parent
c1.printChild(); // Child1
c2.printParent(); // Parent
c2.printChild(); // Child2

복합 상속 (Multiple Inheritance) - 인터페이스 (Interface) 이용

interface Parent1 {
    public void printParent1();
}

interface Parent2 {
    public void printParent2();
}

class Child implements Parent1, Parent2 {
    @Override
    public void printParent1() {
        System.out.println("Parent1");
    }

    @Override
    public void printParent2() {
        System.out.println("Parent2");
    }

    public void printChild() {
        System.out.println("Child");
    }
}

Child c = new Child();
c.printParent1(); // Parent1
c.printParent2(); // Parent2
c.printChild(); // Child

하이브리드 상속 (Hybrid Inheritance)

위 상속 유형들의 중첩

자식 클래스 (Sub Class, Child Class) 에서 일어나는 것들

  • 상속받은 필드, 메서드는 즉시 사용할 수 있다.
  • 자식 클래스에서 새로운 필드, 메서드를 정의할 수 있다.
  • 부모 클래스와 동일한 이름, 파라미터를 가지는 메서드를 새로 작성하려면 오버라이딩 해야한다.
  • 부모 클래스의 정적 메서드를 재정의하는경우, 오버라이딩 되는 것이 아니라 감춰진다. (hiding)
  • 자식 클래스의 생성자에 super 키워드를 사용하여 부모 클래스의 필드들을 주입할 수 있다.

상속 사용의 장점

  • 코드 재사용성 향상 (Code Reuseability) : 자식 클래스에서 부모 클래스의 필드와 메서드를 사용할 수 있으므로
  • 추상화 (Abstraction) : 인터페이스, 추상 클래스처럼 코드 내부를 보지 않고 사용할 수 있으므로
  • 클래스 계층화 (Class Hierarchy) : 현실의 객체 구조와 일치하는 클래스 구조 설계 가능
  • 다형성 (Polymorphism) : 부모 클래스의 메서드를 오버라이딩 하므로 생성되는 인스턴스마다 다른 형태를 지니게 할 수 있으므로

상속 사용의 단점

  • 코드만 보는 것이 아니라 클래스 계층을 이해해야 하므로 복잡성이 늘어난다.
  • 부모 클래스와 자식 클래스간에 관계를 갖게 되므로, 유지보수성에서 손해를 본다.

정리

  • 자바의 기본 클래스인 Object 클래스를 제외하면 기본적으로 우선 상속구조를 가지지 않는다.
  • 클래스를 통해 피상속할 수 있는 부모 클래스는 1개이다.
  • 생성자는 기본인자가 아니라서 상속되지 않지만, super 키워드를 사용해 주입할 수 있다.
  • private 접근자를 가진 필드나 메서드는 상속되지 않는다.
    • 하지만 부모 클래스에서 private 필드 또는 메서드를 사용하는 인자가 protected 또는 public 이라면 그 인자를 상속받아 private 필드에 접근할 수 있다.

Reference

'Java' 카테고리의 다른 글

자바의 추상화  (1) 2024.02.06
자바의 다형성  (0) 2024.02.04
자바의 인터페이스  (0) 2024.02.04
자바의 패키지  (0) 2024.02.02
자바의 클래스(Class)와 객체(Object)  (1) 2024.02.01