본문 바로가기
Backend/Java

Java 기초 문법 : 클래스간의 관계 - 상속과 포함

by 코딩쥐 2024. 6. 9.

상속

기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것으로 두 클래스를 부모(조상 클래스)와 자식(자손 클래스)의 관계로 맺어준다. 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경에 용이하다. Java에서는 단일 상속만을 허용한다. 또한 부모가 없는 클래스는 자동적으로 Object클래스를 상속받게 되어,  Object 클래스에 정의된 11개의 메서드를 포함한다.

  • class 상속할 클래스명 extends 상속받을 클래스명{}

 

상속의 특징

  • 생성자와 초기화 블럭을 제외하고 자손은 조상의 모든 멤버를 상속 받는다. 
  • 자손의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
  • 자손의 변경은 조상에 영향을 미치지 않는다. 
package com.example1;

class Tv {
    boolean power;
    int channel;

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

class SmartTv extends Tv{ // SmartTv는 Tv의 모든 멤버를 상속 받음
    //스마트티비에 자막보여주는 기능 추가
    void displayCaption(String caption) {
            System.out.println(caption);
    }
}

public class Example2{
    public static void main(String[] args) {
        //SmartTv 인스턴스 생성
        SmartTv stv = new SmartTv();
        stv.channel = 10;
        stv.channelUp();
        System.out.println(stv.channel);  // 11
        stv.displayCaption("Hello world"); // Hello world
    }
}

 

오버라이딩

상속받은 조상의 메서드를 자신에 맞게 변경할 수 있다. 오버라이딩 후에 상속받은 조상의 메서드를 사용하고 싶으면 super.메서드명() 을 사용해서 사용이 가능하다. 

 

오버라이딩 조건

  • 메서드의 선언부는 조상 클래스의 메서드와 일치해야 한다. 
  • 접근제어자(public, protected, (default), private)를 조상클래스의 메서드보다 좁은 범위로 변경할 수 없다.
  • 인스턴스 메서드를 static 또는 그 반대로 변경할 수 없다. 
package com.example1;

class Tv {
    boolean power;
    int channel;

    void power() { power = !power; }

    // 부모 클래스의 메서드
    void channelUp() {
        ++channel;
        System.out.println("부모 클래스 channelUp 시행됨");
    }

    void channelDown() { --channel; }
}

class SmartTv extends Tv { // SmartTv는 Tv의 모든 멤버를 상속 받음
    void displayCaption(String caption) {
        System.out.println(caption);
    }

    @Override
    void channelUp() { // 부모 클래스의 메서드를 오버라이딩
        super.channelUp(); // 부모의 메서드를 호출하여 1 증가
        channel += 5; // 그 후 5를 더한다
    }
}

public class Example2 {
    public static void main(String[] args) {
        // SmartTv 인스턴스 생성
        SmartTv stv = new SmartTv();
        stv.channelUp(); // 오버라이딩된 메서드 호출
        System.out.println(stv.channel); // 6
    }
}


포함

클래스의 멤버 변수로 다른 클래스의 인스턴스를 포함하는 것을 의미한다. 단위별로 여러 개의 클래스를 작성한 다음 이 단위 클래스들을 포함관계로 재사용하면 보다 간결하고 손쉽게 클래스를 작성할 수 있다. 포함 관계는 "has-a" 관계로 표현한다.

 

아래 예시는 Circle이 Point 클래스의 인스턴스를 포함하고 있는 예시이다.

package com.example1;
class Point{
    int x;
    int y;
}

//포함관계 (원(Circle)은 점(Point)을 가지고 있다)
class Circle {
    Point p = new Point();
    int r;
}

public class Example2 {
    public static void main(String[] args) {
        Circle c = new Circle();
        c.p.x = 1;
        c.p.y = 2;
        c.r = 3;

        System.out.println("c.p.x=" + c.p.x);
        System.out.println("c.p.y=" + c.p.y);
        System.out.println("c.r=" + c.r);
    }
}