[Java] 상속 ①

kiteB·2022년 1월 2일
0

Java

목록 보기
13/35
post-thumbnail
post-custom-banner

[ 상속 ]

상속(Inheritance)이란 기존의 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것을 의미한다.
상속은 캡슐화, 추상화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나이다.

상속을 통해 기존에 정의되어 있는 클래스의 모든 필드와 메소드를 물려받아, 새로운 클래스를 생성할 수 있다.

  • 기존에 정의되어 있던 클래스부모 클래스(parent class) 또는 상위 클래스(super class), 기초 클래스(base class)라고도 한다.
  • 상속을 통해 새롭게 작성되는 클래스자식 클래스(child class) 또는 하위 클래스(sub class), 파생 클래스(derived class)라고도 한다.

상속의 장점

  • 기존에 작성된 클래스를 재활용할 수 있어, 하위 객체를 쉽고 빠르게 설계할 수 있으며 반복된 코드의 중복을 줄여준다.
  • 상위 객체의 수정으로 모든 하위 객체들의 수정 효과를 가져오므로 유지 보수 시간을 최소화한다.
  • 클래스 간의 계층적 관계를 구성함으로써 다형성의 문법적 토대를 마련한다.

[ 클래스 상속 ]

어떤 클래스를 상속을 하고자할 때, 다음과 같이 extends 키워드를 사용하면 된다.

class 자식클래스 extends 부모클래스 {
    //필드
    //생성자
    //메소드
}

예제 | 부모 클래스 상속 받기

다음과 같이 코드를 작성하면, Dog 클래스가 Animal 클래스를 상속받게 된다.

class Dog extends Animal {
}

🚫 자바는 다중 상속을 허용하지 않는다!
즉, 여러 개의 부모 클래스를 상속할 수 없다. 그러므로 extends 뒤에는 하나의 부모 클래스만 와야 한다.

🔗 참고 | 자바가 다중 상속을 허용하지 않는 이유 - 다이아몬드 문제!
https://siyoon210.tistory.com/125

예제 | Person 클래스 상속 받는 Student 클래스

  • Person
public class Person {

    //필드
    int age;
    String name;
    
    //생성자
    Person(int age, String name) {
       this.age = age;
       this.name = name;
    }
    
    //메소드
    void print() {
        System.out.println("나이: " + age + "\n" + "이름: " + name + "\n");
    }

}
  • Student
public class Student extends Person {

    //필드
    String school;

    //생성자
    Student(int age, String name, String school) {
        this.age = age;
        this.name = name;
        this.school = school;
    }
    
    //메소드
    void print() {
        System.out.println("나이: " + age + "\n" + "이름: " + name + "\n" + "학교: " + school + "\n");
    }

    void goToSchool() {
        System.out.println(school + "로 등교하다.");
    }
    
}
  • Worker
public class Worker extends Person {

    //필드
    String company;
    
    //생성자
    Worker(int age, String name, String company) {
        this.age = age;
        this.name = name;
        this.company = company;
    }
    
    //메소드
    void print() {
        System.out.println("나이: " + age + "\n" + "이름: " + name + "\n" + "회사: " + company + "\n");
    }

    void goToWork() {
        System.out.println(company + "로 출근하다.");
    }
}
  • 테스트 코드
public class PersonExample {
    public static void main(String[] args) {
    
        //Person 객체 생성
        Person person = new Person(10, "Kite");
        person.print();
        
        //Student 객체 생성
        Student student = new Student(24, "YJ", "SCH");
        student.goToSchool();
        student.print();
        
        //Worker 객체 생성
        Worker worker = new Worker(30, "Kim", "A Company");
        worker.goToWork();
        worker.print();

    }

}
  • 실행 결과
나이: 10
이름: Kite

SCH로 등교하다.
나이: 23
이름: YJ
학교: SCH

A Company로 출근하다.
나이: 30
이름: Kim
회사: A Company

[ 부모 생성자 호출 ]

자바에서는 자식 객체를 생성하면, 부모 객체가 먼저 생성되고 자식 객체가 그 다음에 생성된다.

Dog 클래스가 Animal을 상속 받은 클래스라고 할 때, 아래 코드는 Dog 객체만 생성하는 것처럼 보이지만 사실 내부적으로는 부모인 Animal 객체가 먼저 생성되고 Dog 객체가 생성된다.

Dog dog = new Dog();

부모 생성자는 자식 생성자의 맨 첫 줄에서 호출된다.

예를 들어 Dog 의 생성자가 명시적으로 선언되지 않았다면 컴파일러는 다음과 같은 기본 생성자를 생성해낸다.

public Dog() {
    super();
}

super()는 부모의 기본 생성자를 호출한다.
이 예제에서는 다음과 같이 Animal의 기본 생성자를 호출한다.

public Animal() {
}

기본 생성자를 선언하지 않았을 때 컴파일러에 의해 기본 생성자가 만들어지므로 문제없이 실행된다.
만약 직접 자식 생성자를 선언하고 명시적으로 부모 생성자를 호출하고 싶다면 다음과 같이 작성하면 된다.

자식클래스(매개변수선언, ...) {
    super(매개값, ...);
    ...
}

super(매개값, ...)는 매개값의 타입과 일치하는 부모 생성자를 호출한다.
만약 매개값의 타입과 일치하는 부모 생성자가 없을 경우 컴파일 오류가 발생한다.

예제

  • People
public class People {

    public String name;
    public String ssn;
    
    public People(String name, String ssn) {
        this.name = name;
        this.ssn = ssn;
    }
}
  • Student
public class Student extends People {

    public int studentNo;
    
    public Student(String name, String ssn, int studentNo) {
        super(name, ssn);
        this.studentNo = studentNo;
    }
    
}

위의 코드에서 super(name, ssn) 코드가 빠지면 컴파일 오류가 발생한다.

  • 테스트
public class StudentExample {
    public static void main(String[] args) {
    
        Student student = new Student("Bae", "123456-1234567", 1);
        System.out.println("name : " + student.name);
        System.out.println("ssn : " + student.ssn);
        System.out.println("studentNo : " + student.studentNo);
        
    }
}
  • 실행 결과
name : Bae
ssn : 123456-1234567
studentNo : 1

[ 참고자료 ]

이것이 자바다 책
http://tcpschool.com/java/java_inheritance_concept

profile
🚧 https://coji.tistory.com/ 🏠
post-custom-banner

0개의 댓글