자바_상속

상속(inheritance)

상속의 정의

기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것이다. 상속을 통해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고, 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이하다.

상속을 구현하는 방법

class Parent{}
class Child extends Parent{
	// ...
}

조상 클래스 : 부모(parent)클래스, 상위(super)클래스
자손 클래스 : 자식(child)클래스, 하위(sub)클래스

상속의 예시

class Tv {
    boolean power; // 전원 상태(on/off)
    int channel;    // 채널

    void power() {
        power = !power;}
    void channelUp() {
        ++channel;
    }
    void channelDown(){
        --channel;
    }
}

class CaptionTv extends Tv{
    boolean caption;    // 캡션 상태(on/off)
    void displayCaption(String text) {
        if(caption){ // 캡션 상태가 on(true)일 때만 text를 보여준다.
            System.out.println(text);
        }
    }
}

class CaptionTvTest {
    public static void main(String[] args) {
        CaptionTv ctv = new CaptionTv();
        ctv.channel = 10;
        ctv.channelUp();
        System.out.println(ctv.channel);
        ctv.displayCaption("Hello World!");
        ctv.caption = true;
        ctv.displayCaption("Hello World!");
    }
}

실행결과
11
Hello World!

상속에 대해서 알 수 있는 것들

  1. 부모와 자식 관계에서 클래스의 멤버변수와 메서드를 상속 받았을 때, 자식은 부모클래스의 멤버변수와 메서드를 사용할 수 있다.
  2. 상속을 통해서 하나의 클래스에 다양한 기능을 넣어서 편한 코드작성이 가능하다.

포함관계

상속이외에도 클래스를 재사용하는 또 다른 방법이 있다. 그것은 클래스간에 '포함(Composite)'관계를 맺어 주는 것이다.
클래스 간의 포함관계를 맺어 주는 것은 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것을 뜻한다.

class Circle {
	int x;	// 원점의 x좌표
    int y;	// 원점의 y좌표
    int z;	// 반지름(radius)
}

class Point {
	int x;	// x좌표
    int y;	// y좌표
}

이때 포함관계를 활용해서 Circle클래스를 다음과 같이 작성할 수 있다.

class Circle{
	Point c = new Point();	// 원점
    int r;
}

원(Circle)은 점(Point)이다. - Circle is a Point.
원(Circle)은 점(Point)를 가지고 있다. - Circle has a Point.

상속관계 : '~은 ~이다.(is-a)'
포함관계 : '~은 ~을 가지고 있다.(has-a)'

상속과 포함관계의 예시

class DrawShape {
    public static void main(String[] args) {
        Point [] p = { new Point(100, 100), new Point(140, 50), new Point(200, 100)};
        Triangle t = new Triangle(p);
        Circle c = new Circle(new Point(150, 150), 50);

        t.draw();   // 삼각형을 그린다.
        c.draw();   // 원을 그린다.
    }
}

class Shape {
    String color = "black";
    void draw(){
        System.out.printf("[color=%s]%n", color);
    }
}

class Point {
    int x;
    int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    Point() {
        this(0,0);
    }

    String getXY() {
        return"(" + x + ", " + y + ")";     // x와 y의 값을 문자열로 반환
    }
}

class Circle extends Shape {
    Point center;   //  원의 원점좌표
    int r;      // 반지름

    Circle() {
        this(new Point(0,0), 100); // Circle(Point center, int r)를 호출
    }

    Circle(Point center, int r){
        this.center = center;
        this.r = r;
    }

    void draw() {
        System.out.printf("[center = (%d, %d), r = %d, color = %s]%n", center.x, center.y, r, color);
    }
}

class Triangle extends Shape{
    Point [] p = new Point[3];

    Triangle(Point[] p){
        this.p = p;
    }

    void draw() {
        System.out.printf("[p1 = %s, p2 = %s, p3 = %s, color = %s]%n", p[0].getXY(), p[1].getXY(), p[2].getXY(), color);
    }
}

실행결과
[p1 = (100, 100), p2 = (140, 50), p3 = (200, 100), color = black]
[center = (150, 150), r = 50, color = black]

class Circle extends Shape {	//  Circle과 Shape는 상속관계
    Point center;   		//  Circle과 Point는 포함관계
    int r;      		// 반지름

위와 같이 상속과 포함의 관계를 구분할 수 있다면 클래스의 함수를 보다 유기적으로 활용할 수가 있다.

class Shape {
    String color = "black";
    void draw(){	
        System.out.printf("[color=%s]%n", color);
    }
}

Circle클래스는 Shape클래스로부터 모든 멤버를 상속받았으므로, Shape클래스에 정의된 color이나 draw()를 사용할 수 있다.

class Circle extends Shape {
  	...
    void draw() {	// 원을 그리는 대신에 원의 정보를 출력하도록 했다.
        System.out.printf("[center = (%d, %d), r = %d, color = %s]%n", center.x, center.y, r, color);
    }
}

Circle클래스에도 Shape클래스에 있는 draw()메서드가 정의되어 있는 것을 알 수가 있다. 이때 draw()를 호출할 경우 Circle클래스에 정의된 draw()가 호출된다.
이를 오버라이딩(overriding)이라고 부른다.

참고 자바의 정석 p310 ~ p321

좋은 웹페이지 즐겨찾기