본문 바로가기
Java 강의

자바 상속 / java inheritence

by 자유코딩 2017. 9. 23.

이번 글에서는 자바의 상속에 대해서 알아보도록 하겠습니다.

 

자바와 같은 객체지향(Object Oriented) 프로그래밍 언어에는 상속이라는 개념이 있습니다

 

사람들은 부모로부터 상속을 받기도 합니다.

 

재능, 재산, 성격 등 많은 것들을 물려받습니다.

 

자바에도 사람들의 상속과 유사한 상속의 개념이 있습니다.

 

자바에서 상속을 해주는 클래스를 상위클래스 , 부모 클래스라고 합니다

 

상속을 받는 클래스는 하위클래스 , 자식클래스 , Derived 클래스 , 유도 클래스라고 합니다

 

사람들의 상속과 다르게 자바에서의 상속은 상위 클래스의 속성과 메소드들을 하위 클래스로 물려줍니다 

상위 클래스는 하위 클래스에게 상속해줍니다.

 

하위 클래스는 상위 클래스로부터 상속 받습니다

 

객체 지향 프로그래밍 언어에는 Java , C# , C++등이 있습니다

 

기본적인 상속을 하는 소스코드를 보겠습니다

1
2
3
4
5
6
7
8
9
10
class Parents{
 
}
public class Child extends Parents{
 
    public static void main(String[] args){
        System.out.println("extends를 사용해서 상속했습니다");
 
    }
}
cs

 

출력 결과

소스코드에서 상속을 하게 해주는 키워드는 extends 입니다

 

public class Child extends Parents{} 이렇게 코드를 작성하면 Child 클래스는 Parents 클래스로부터 상속 받게 됩니다.

정리하면 이렇습니다.

상위 클래스 : 상속이 되어 지는 클래스

자식 클래스 , 유도 클래스 , 하위 클래스 Derived: 상속을 받는 클래스

하위 클래스는 자기가 상속하는 상위 클래스의 모든 멤버를 하위 클래스의 생성자에서 초기화 할 의무를 가진다.

상위 클래스의 멤버는 상위클래스의 생성자를 통해서 초기화 하는 것이 타당하다.

 

상속관계에 있는 인스턴스의 생성과정

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
31
32
33
public class Car {//상위 클래스
    private int speed;
    private int gear;
    private String color;
    
    public int getSpeed() {
        return speed;
    }
    public String toString() {
        return "";
    }
    public void speedUp(int num) {
        this.speed = this.speed + num;
    }
    public void speedDown(int num) {
        this.speed = this.speed - num;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public int getGear() {
        return gear;
    }
    public void setGear(int gear) {
        this.gear = gear;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
}
cs

 

1
2
3
4
5
public class SportCar extends Car{//하위 클래스
    //텅 비어있다
    //그런데 상속을 받았다
    //그래서 하위 클래스의 인스턴스는 상위 클래스 Car의 함수들을 쓸 수 있다
}
cs

 

1
2
3
4
5
6
7
8
9
public class CarTest {
    public static void main(String[] args) {
        SportCar sCar = new SportCar();
        //자식 클래스의 인스턴스를 생성했다.
        sCar.setColor("red");
        //그런데 상위 클래스의 메소드 setColor를 사용 할 수 있다.
        //이게 바로 상속이다.
    }
}
cs

 

자식 클래스의 인스턴스를 가지고 부모 클래스의 함수에 접근 할 수 있습니다.

 

부모 클래스의 인스턴스와 자식 클래스의 인스턴스를 볼 때 마치 부모로부터 자식이 상속 받고 있는 것으로 보입니다.

 

this와 super키워드

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Parent{
    int data = 100;
    public Parent() {
        System.out.println("부모 생성자");
    }
    public Parent(int data) {
        this.data = data;
        //this는 자기 참조 연산자로써 인스턴스 자신을 지칭한다
    }
    public void print() {
        System.out.println("부모다");
        // TODO Auto-generated method stub
    }
}
class Child extends Parent{
    int data = 200;
    public Child(int a,int b) {
        super(200);//super는 부모 클래스를 가리킨다
    //super();부모 클래스의 기본 생성자를 호출한다
    //선언하지 않아도 암묵적으로 정의되어 있다
    //부모 생성자에 선언되어있는 생성자에 맞춰서 super(); 호출
        System.out.println("자식 생성자");
    }
    public Child() {
        this(14);//this키워드가 속한 클래스 자기 자신을 가리킨다
        //그래서 Child(int a,int b)에 1과 4를 전달한다
    }
    public void print() {
        int data = 300;
        super.print();//부모 클래스의 print()함수를 호출한다
        System.out.println("자식이다");
    }
}
public class ParentTest {
    public static void main(String[] args) {
        Child c = new Child();
        //자식 객체가 생성이 될때
        //부모 객체와 자식 객체를 모두 만듬
        //부모 생성자와 자식 생성자를 모두 호출
        //호출 순서
            //자식 클래스의 생성자를 먼저 호출
            //자식 클래스의 생성자는 실행 전 부모 생성자를 호출
        //실행 순서
            //부모 클래스 생성자가 먼저 실행되고
            //자식 클래스 생성자가 실행
    }
}
cs

 

●상속에 대해 쉽게 가질 수 있는 편견과 중요한 이야기

 

하위 클래스에서는 상위 클래스의 속성과 메소드를 사용 할 수 있습니다

 

상위 클래스의 속성과 메소드를 아주 간편하게 재사용 할 수 있습니다

 

그렇지만 상속은 이런 재사용 , 재활용을 위해서 존재하는 문법이 아닙니다

 

상속의 진정한 의미와 목적은 연관된 일련의 클래스에 대한 공통적인 규약을 정의하고 적용하는 것 입니다.

 

정말로 재사용이 하고 싶다면 사실 코드를 복사 , 붙여넣기를 하면 됩니다. 그게 더 빠르게 코드를 작성하는 방법이 될 수도 있습니다.

 

그래서 객체지향은 재활용의 관점에서는 실패한 패러다임 입니다

 

객체 지향은 재활용의 관점에서 등장한 개념은 맞습니다.

 

그러나 많은 소프트웨어 공학자들도 2000년대에 객체지향은 재활용의 관점에서 실패한 패러다임이라고 밝혔습니다

 

상속의 전체 의미를 100이라고 한다면 재활용이 10이고 이러한 공통된 규약의 적용에 관한 것이 90을 차지한다고 볼 수 있습니다

 

정말로 시간과 노력이 적게 들게 해주는 패러다임은 오히려 컴포넌트 기반 개발( Component Based Development ( CBD ))입니다.

 

컴포넌트 = 작은 소규모 정도의 클래스가 아니고 30개 1000개 이상의 클래스가 모인 집합체

 

객체 지향이 재활용의 관점에서 실패한 이유를 개발자의 입장에서 보겠습니다

 

개발자의 생각 순서 1. 클래스 A를 재활용 해야겠다

개발자의 생각 순서 2. 이 때, 재활용하려는 클래스가 잘 정의 되었다면 코드가 1000줄을 넘을 수 없다. 클래스의 크기가 작다

개발자의 생각 순서 3. 그 작은 클래스를 재활용하는 노력보다 새로 만드는게 더 적은 노력이 들겠다는 생각이 든다

 

표와 같은 사고의 과정이 일어납니다. 그리고 개발자는 다른 개발자가 개발한 코드에 대해서 System.out.println만큼 신뢰하지 않습니다.

 

그러므로 협업시에도 상속은 재활용의 관점으로 바라봐서는 안됩니다.

 

이번 글에서는 상속에 대해서 알아보았습니다.

jswoo030@gmail.com 으로 질문을 보내시면 빠른 답변을 받으실 수 있습니다.

댓글