본문 바로가기
Programming/Java

[자바/Java] 상속(inheritance)

by 코딩하는 랄로 2023. 9. 29.
728x90

상속이란?

상속은 자바의 핵심 개념 중 하나이다. 상속은 이름 그대로 부모가 자식에게 재산을 물려주는 것과 유사한 의미이다. 

 

현실 세계에서 상속과의 차이점은 자바에서의 상속은 자식 클래스가 상속 받고 싶은 부모의 클래스를 선택해서 물려받는 것이다. 이 때에 상속 받는 클래스를 자식 클래스, 하위 클래스 또는 서브 클래스라고 부르고 상속을 해주는 클래스는 부모 클래스, 상위 클래스 또는 슈퍼 클래스라고 한다.

 

상속을 하는 이유는 유지 보수가 쉽고 중복이 적고 통일성이 생기기 때문이다. 예를 들어, 핸드폰에는 아이폰, 갤럭시 등 수많은 종류의 휴대폰이 있지만 모든 핸드폰이 공통적으로 가지고 있는 기능들이 존재한다.

 

이 때, 이 공통된 기능(메소드)들을 핸드폰(클래스)을 만들때마다 구현을 하는 건 너무 비효율적이고 공통된 기능이 변경되었을 경우, 모든 핸드폰들의 기능을 하나 하나 변경해주어야 한다. 

 

이 때에 이런 공통된 기능들을 하나의 클래스로 규정하고 이 기능들이 필요한 클래스들이 상속받게 한다면, 훨씬 유지 보수가 쉽고 중복 코드가 적어지고 통일성을 가지는 프로그래밍을 할 수 있는 것이다.

 

 

 

상속의 사용

상속을 받는 방법은 자식 클래스 뒤에 extends 키워드를 통해 상속 받고 싶은 부모 클래스를 명시해 주면 된다. 이 때에 상속받는 부모클래스는 하나만 받을 수 있다.

class Parent { 

    //Field
    
    
    //Constructor
    
    
    //Method
    
}

class child1 extends Parent { }

class child2 extends Parent { }

 

이렇게 상속 받을 경우 자식 클래스로 인스턴스를 생성하게 되면 부모 클래스의 필드와 메소드들을 사용할 수 있다.

class Parent {
    String name;
    
    Parent(String name) {
        this.name = name;
    }
    
    public void printName() {
        System.out.println(name);
    }
}

class Child extends Parent {
    Child(String name) {
        super(name);
    }
}

class Main {
    public static void main(String[] args) {
        Child c = new Child("HongGilDong");
        c.printName();  // HongGilDong
    }
}

 

 

 

Super

위의 child 클래스의 생성자를 보면 super라는 키워드를 볼 수 있다. super는 상속 받은 자식 클래스에서 부모클래스의 인스턴스를 호출 할 때 사용된다.

 

일반적인 메소드에서도 사용할 수 있지만, 생성자 내에서 사용할 경우 부모 클래스의 생성자를 호출하여 부르게 되는  것이다. 상속 받은 자식클래스에서는 생성자를 호출시 super를 통해 부모 생성자를 무조건 호출하여 주어야 한다.

 

그렇기 때문에 파라미터가 존재하는 기본생성자 이외에 생성자의 경우에서 super를 통해 생성자를 호출하기 위해서는 부모 클래스에서 해당 생성자가 선언되어 있어야 한다. (기본 생성자에서는 super() 생략 가능)

 

 

 

오버라이딩(Overriding)

상속을 할 경우에, 부모 클래스의 메소드를 그대로 사용하여도 되지만 오버라이딩을 통해 해당 메소드를 덮어씌워 사용하여도 된다.

 

오버로딩의 경우에는 파라미터 수, 리턴 타입, 파리미터의 순서가 달라야 하지만 오버라이딩은 모두 같아야 한다. (다르면 에러 발생!!) 왜냐하면, 오버라이딩은 해당 메소드의 기능부만을 덮어씌우는 것이기 때문에 기능부를 제외한 다른 것은 모두 같아야 한다.

 

예를 들어, 위의 예시에서 child 클래스에 다시 printName을 다음과 같이 오버라이딩할 수 있다.

class Parent {
    String name;
    
    Parent(String name) {
        this.name = name;
    }
    
    public void printName() {
        System.out.println(name);
    }
}

class Child extends Parent {
    Child(String name) {
        super(name);
    }
    
    @Override
    public void pirntName() {
        System.out.println("반갑습니다");
        super.printName();
    }
}

class Main {
    public static void main(String[] args) {
        Child c = new Child("HongGilDong");
        c.printName();
        //반갑습니다.
        //HongGilDong
    }
}

 

 

 

상속과 접근 권한

  • private : 자기 클래스에서만 사용 가능
  • default : 자기 클래스 + 같은 패키지 안에서 사용 가능
  • protected : 자기 클래스 + 같은 패키지 + 상속 클래스에서 사용 가능
  • public  : 어디서나 직접 사용 가능
728x90