상속(Inheritance)

김수민·2023년 3월 11일
0

백엔드 부트캠프

목록 보기
13/52

상속

  • 상속: 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 자바의 문법 요소
  • 두 클래스를 상위 클래스와 하위 클래스로 나누어 상위 클래스의 멤버(필드, 메서드, 이너 클래스를)를 하위 클래스와 공유하는 것
  • 이 두 클래스를 서로 상속 관계에 있다고 하며, 하위 클래스는 상위 클래스가 가진 모든 멤버를 상속받게 됨
  • 하위 클래스의 멤버 개수는 언제나 상위 클래스의 그것과 비교했을 때 같거나 많음
  • Programmer 클래스는 이름, 나이, 회사이름이 있고, 기능으로 배우기, 걷기, 먹기, 코딩하기가 정의되어 있음
  • Dancer 클래스에는 속성으로 이름, 나이, 그룹명이 있고, 기능으로 배우기, 걷기, 먹기, 춤추기가 있음
  • Singer 클래스에는 속성으로 이름, 나이, 밴드명이 있고, 기능으로 배우기, 걷기, 먹기, 노래하기가 있음

=> 사람이라면 누구나 이름과 나이가 있고, 무언가를 배우고 먹고 걷는 일을 한다는 공통적인 특성이 있음

  • 사람 클래스가 상위 클래스, 그리고 프로그래머, 댄서, 가수 클래스가 상위 클래스로부터 특정한 속성과 기능을 내려받는(또는 확장된) 하위 클래스가 됨

  • 코드를 재사용하여 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있어 코드의 중복을 제거할 수 있음

  • 상속은 다형적 표현이 가능함
    예. '프로그래머는 프로그래머이다' -> 참
    '프로그래머는 사람이다' -> 참
    하나의 객체가 여러 모양으로 표현될 수 있다는 것 = 다형성

클래스를 상속할 때에는 extends 키워드를 사용하며, 클래스명 다음에 extends 상위 클래스명을 사용하여 정의

class Person {
    String name;
    int age;

    void learn(){
        System.out.println("공부를 합니다.");
    };
    void walk(){
        System.out.println("걷습니다.");
    };
    void eat(){
        System.out.println("밥을 먹습니다.");
    };
}

class Programmer extends Person { // Person 클래스로부터 상속. extends 키워드 사용 
    String companyName;

    void coding(){
        System.out.println("코딩을 합니다.");
    };
}

class Dancer extends Person { // Person 클래스로부터 상속
    String groupName;

    void dancing(){
		    System.out.println("춤을 춥니다.");
		};
}

class Singer extends Person { // Person 클래스로부터 상속
    String bandName;

    void singing(){
		    System.out.println("노래합니다.");
		};
    void playGuitar(){
		    System.out.println("기타를 칩니다.");
		};
}

public class HelloJava {
    public static void main(String[] args){

        //Person 객체 생성
        Person p = new Person();
        p.name = "김코딩";
        p.age = 24;
        p.learn();
        p.eat();
        p.walk();
        System.out.println(p.name);

        //Programmer 객체 생성
        Programmer pg = new Programmer();
        pg.name = "박해커";
        pg.age = 26;
        pg.learn(); // Persons 클래스에서 상속받아 사용 가능
        pg.coding(); // Programmer의 개별 기능
        System.out.println(pg.name);

    }
}

//출력값
공부를 합니다.
밥을 먹습니다.
걷습니다.
김코딩
공부를 합니다.
코딩을 합니다.
박해커

자바의 객체지향 프로그래밍에서는 단일상속(single inheritance)만을 허용함. -> 다중상속은 허용하지 않음

포함 관계

포함(composite): 상속처럼 클래스를 재사용할 수 있는 방법. 클래스의 멤버로 다른 클래스 타입의 참조변수를 선언하는 것.

public class Employee {
    int id;
    String name;
    Address address;

    public Employee(int id, String name, Address address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    void showInfo() {
        System.out.println(id + " " + name);
        System.out.println(address.city+ " " + address.country);
    }

    public static void main(String[] args) {
        Address address1 = new Address("서울", "한국");
        Address address2 = new Address("도쿄", "일본");

        Employee e = new Employee(1, "김코딩", address1);
        Employee e2 = new Employee(2, "박해커", address2);

        e.showInfo();
        e2.showInfo();
    }
}

class Address {
    String city, country;

    public Address(String city, String country) {
        this.city = city;
        this.country = country;
    }
}

// 출력값
1 김코딩
서울 한국
2 박해커
도쿄 일본
  • 한 회사의 근로자(Employee)를 표현하기 위한 Employmee 클래스의 멤버 변수로 근로자가 사는 개략적인 주소를 나타내는 Address 클래스가 정의되어 있음

  • 원래라면 Address 클래스에 포함되어 있는 인스턴스 변수 city와 country를 각각 Employee 클래스의 변수로 정의해주어야하지만, Address 클래스로 해당 변수들을 묶어준 다음 Employee 클래스 안에 참조변수를 선언하는 방법으로 코드의 중복을 없애고 포함관게로 재사용함

  • 클래스 간의 관계가 '~은 ~이다(IS-A)'관계인지 '은 ~을 가지고 있다(HAS-A)' 관계인지 생각
    예. Employee는 Address이다. -> 성립하지 않음
    Employee는 Address를 가지고 있다 -> 성립
    --> 상속보다는 포함관계가 적합
    예. Car 클래스와 SportsCar 클래스가 있다고 할 때,
    SportsCar는 Car를 가지고 있다. 라는 문장보다 SportsCar는 Car이다. 라는 문장이 더 자연스러움.
    --> Car를 상위클래스로 하는 상속관계를 맺어주는 것이 적합.

메서드 오버라이딩

  • 메서드 오버라이딩(Method Overiding): 상위 클래스로부터 상속받은 메서드와 동일한 이름의 메서드를 재정의하는 것
    -상위 클래스의 메서드를 오버라이딩 하려면 세 가지 조건을 반드시 만족시켜야 함
    1. 메서드의 선언부(메서드 이름, 매개변수, 반환타입)이 상위클래스의 그것과 완전히 일치해야함.
    2. 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야 함.
    3. 예외는 상위 클래스의 메서드보다 많이 선언할 수 없음.

super 키워드와 super()

super키워드는 상위 클래스의 객체, super()는 상위 클래스의 생성자를 호출하는 것
공통적으로 모두 상위 클래스의 존재를 상정하며 상속 관계를 전제로 함

super

하위 클래스는 상위 클래스로부터 변수를 상속받는데, 자신의 인스턴스 변수 이름이 같다면 둘을 구분할 방법이 필요함. -> 이 때 사용되는 방법이super 키워드
super 키워드를 붙이지 않는다면, 자바 컴파일러는 해당 객체는 자신이 속한 인스턴스 객체의 멤버를 먼저 참조함.
반면 경우에 싸라서 상위 클래스의 변수를 참조해야할 경우가 종종 있는데 그 경우 super 키워드를 사용하면 부모의 객체의 멤버의 값을 참고할 수 있음.

super()

-super()는 상위 클래스의 생성자를 호출하는데 사용됨
-this()와 마찬가지로 생성자 안에서만 사용가능하고, 반드시 첫 줄에 와야힘

클래스의 정점, Object 클래스

  • Oject class: 자바의 클래스 상속계층도에서 최상위에 위치한 상위클래스
  • '자바의 모든 클래스는 Object 클래스로부터 확장된다' --> 참
메서드명반환 타입주요 내용
toString()String객체 정보를 문자열로 출력
equals(Object obj)boolean등가 비교 연산(==)과 동일하게 스택 메모리값을 비교
hashCode()int객체의 위치정보 관련. Hashtable 또는 Hashmap에서 동일 객체여부 판단
waitvoid현재 쓰레드 일시정지
notify()void일시정지 중인 쓰레드 재동작

0개의 댓글