티스토리 뷰

728x90
반응형

상속

 

상속은 객체지향 프로그래밍의 핵심개념 중 하나다.

 

꼭 자바뿐 아니라, 객체지향 프로그래밍 설계를 지원하는 모든 언어에 적용되는 개념이라고 할 수도 있다.

 


자바 언어에서 상속이란 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 문법요소이다.

 

두 개의 클래스를 상, 하위 클래스로 나누어 상위 클래스의 멤버(필드, 메서드, 내부 클래스)를

 

하위 클래스와 공유하는 것을 의미하기도 한다.

 

이 경우 두 개의 클래스를 상속관계에 있다고 하며, 하위 클래스는 상위 클래스의 모든 멤버를 상속받게 된다.

 

따라서 하위 클래스의 멤버 개수는 언제나 상위 클래스의 멤버 개수보다 같거나 많다.

 

또한 "~클래스로부터 상속받았다"는 표현보다는 "~클래스로부터 확장되었다"가 더 정확한 표현이며,

 

두 클래스 간 상속 관계를 설정할 때 사용하는 키워드가 extends인 것을 보면 명확하다.

 

계속해서 상속에 대한 예를 보자.

 

그림은 한 개의 상위 클래스와 세 개의 하위 클래스로 이루어진 트리구조를 나타낸다.

 

상위 클래스 Person의 필드 name, age와 메서드 learn(), walk(), eat()를

 

하위 클래스가 상속받아 전부 가지고 있음을 알 수 있다.

 

이어서 각각의 하위 클래스마다 필요한 멤버를 새로 정의해서 하위 클래스를 만드는데,

 

공통적인 특성을 상위 클래스에 입력해 둠으로써 코드의 재사용성을 높일 수 있다.

 

또한, 상속은 다형적 표현이 가능하다는 장점이 있다.

 

위 그림에서 '프로그래머는 프로그래머이다'는 참이며, '프로그래머는 사람이다' 역시 참이다.

 

이런 식으로 하나의 객체가 여러 모양으로 표현될 수 있는 것을 다형성이라고 부른다.

 

다형성은 그 자체로 공부가 더 필요한 부분이니, 따로 글을 떼어내 다룬다.

 


자바에서 상속을 구현하는 방법은 매우 간단하다. 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);

    }
}

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

 

위의 트리구조 그림을 코드로 옮겨놓은 것을 볼 수 있다.

 

구체적으로 들여다보면 Person 클래스로부터 Programmer, Dancer, Singer 클래스가 확장되었고,

 

Person 클래스에 있는 속성(필드)과 기능(메서드)들을 사용할 수 있는 것을 알 수 있다.

 

또한 각각의 클래스에서 개별적인 멤버를 정의해주고 있는데,

 

상속이 아니라면 각 클래스의 멤버를 따로따로 모두 선언해주어야 했을 것이고, 이는 코드 중복으로 이어졌을 것이다.

 

끝으로 자바의 객체지향 프로그래밍에서는 단일 상속(single inheritance)만을 허용한다.

 

오로지 하나의 클래스만을 확장해서 사용할 수 있다는 뜻인데, 이는 C++과 구별되는 자바 객체지향의 특징이다.

 


포함 관계

 

포함(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 클래스에 속해야 할 city와 country를 Address 클래스로  따로 묶어,

 

Employee 클래스 안에 참조변수를 선언하는 방법으로 코드의 중복을 없애고, 포함관계로 재사용하고 있다.

 

추가로 객체지향 프로그래밍에선 상속보단 포함관계를 더 많이 사용한다고 한다.

 

그렇다면 클래스 간의 관계에 있어서 상속과 포함 중 어떤 것을 선택할 것인지 정하는 방법은 무엇일까?

 

가장 대표적인 방법은 클래스 간의 관계가 '~은 ~이다(IS-A)' 인지 '~은 '~을 가지고 있다(HAS-A)'인지

 

문장을 만들어 생각해보는 것이다.

 

위의 예를 들어 설명해보자면, 'Employee는 Address이다.'라는 문장은 어색한 반면

 

'Employee는 Address를 가지고 있다.'는 문장은 어색하지 않으므로 상속보다는 포함관계가 적합하다.

 

반면 더 위의 예로 돌아가 'Programmer는 Person이다.'라는 문장이 'Programmer는 Person을 가지고 있다.'는 문장보다

 

적당하므로, 이 경우에는 포함보다는 상속관계가 올바르다고 할 수 있다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함