자바 정복 일기 - 상속과 인터페이스

Bex·2023년 8월 12일
1
post-thumbnail

1. 상속

상속(Inheritance)이란?

  • 상속이란 기존 클래스의 변수와 메소드를 물려 받아 새로운 클래스로 구성하는 것!!!
  • 예를 들어, 참이슬 클래스는 소주 클래스를 상속받아 소주의 특징을 가질 수 있다.

상속의 개념에 대해 알아보았고 그렇다면 왜 상속을 사용할까?

1) 상속의 필요성

상속을 사용함으로써 얻을 수 있는 이점은 다음과 같다.

  1. 기존 클래스의 변수와 코드를 재사용할 수 있어 개발 시간이 단축
  2. 코드를 공통적으로 관리하기 때문에 여러 코드의 추가 및 변경이 용이
  3. 클래스 간 계층적 분류 및 관리가 가능하여 유지보수가 용이

따라서 상속을 통해 더 빠르고 유지보수가 쉽고, 중복이 적고, 통일성이 있는 코드를 작성할 수 있다.


2) 상속의 특징

  1. 부모클래스의 생성자, 초기화 블럭은 상속이 되지 않는다.

    • 자식클래스 객체 생성 시, 부모클래스 생성자가 먼저 실행됨.
    • 자식클래스 생성자 안에서 부모클래스 생성자 호출을 명시하고 싶으면 super();을 입력.
  2. 부모의 private 멤버는 상속은 되지만 접근 불가능하다.

    • 자식클래스 생성 시 부모의 필드값도 전달받은 경우, 자식 생성자 안에서 부모의 private 필드에 직접 초기값 대입할 수 없음.
    • 전달받은 부모 필드값을 부모생성자 쪽으로 넘기는 방법을 이용한다.
      ex) super(전달받은값, ...);
  3. 모든 클래스는 Object 클래스를 상속받는다.

    • Object 클래스가 제공하는 메서드를 오버라이딩해서 메서드 본래 기능을 변경할 수 있음.
    • 모든 클래스는 java.lang.Object를 포함하고 있으며 jvm이 자동으로 추가해줌
      ex) java.lang.String 클래스의 equals()와 toString()

3) 클래스 상속 시 주의사항

  • 여러개의 클래스를 상속할 수 없다.
  • private 접근 제한을 갖는 필드와 메소드는 상속할 수 없다.

4) 클래스 상속 구현

  • 부모클래스를 슈퍼클래스(super class), 상속받는 자식클래스를 서브클래스(sub class)라 한다.
  • 클래스 간의 상속 시 extends 키워드를 사용한다.
class 자식클래스 extends 부모클래스 {
	// 필드
    // 생성자
    // 메서드
}

위에서 말했던 소주 클래스와 참이슬 클래스를 통해 상속을 직접 구현해보자. 여기서 참이슬 클래스가 소주 클래스를 상속받는다고 하자. 그렇다면 참이슬 클래스는 다음과 같이 소주 클래스를 상속받을 수 있다.
class Chamiseul extends Soju { }

이번에는 상위클래스인 소주클래스를 만들어보자

소주 클래스

  • 필드에는 소주 이름을 넣어보자.
  • 메서드에는 마시는 것, 섞는 것의 기능을 넣어보자.
pulic class Soju {

    // 필드 입력
    public String model;
    public double ABV;

    // 생성자(객체 값 세팅)
    public Soju(String model, double ABV) {
        this.model = model;
        this.ABV = ABV;
    }

    // 메서드 입력
    public void drink()	{
        System.out.println(model + "을 마십니다.");
    }
    public void mix() {
        System.out.println(model + "을 맥주에 섞습니다.");
    }

    // Getter 생성
    public String getModel() { return model; }
    public double getABV() { return ABV; }
}

참이슬 클래스

  • 필드에는 종류와 도수(ABV)를 넣어보자.
  • 메서드로 참이슬 종류에 따른 마시는 것을 넣어보자.
public class Chamiseul extends Soju{

    // 필드 입력
    private String type;

    // 생성자 입력
    public Chamiseul(String model, double ABV, String type) {
        super(model, ABV);
        this.type = type;
    }

    // 메서드 입력
    public void typeDrink() {
        System.out.println(model + "소주의 " + type + "종류를 마십니다.");
    }

    // Getter 생성
    public String getType() { return type; }
}

지금까지 만든 참이슬 클래스를 이용하여 출력해보자

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

        // 오리지널 참이슬 객체 생성하기
        Chamiseul original = new Chamiseul("참이슬", 20.1, "오리지널");

        // 참이슬 클래스에서 Soju 클래스의 메서드 사용
        System.out.println("모델명 : " + original.getModel());
        System.out.println("도수 : " + original.getABV());

        // 참이슬 클래스에 존재하는 필드
        System.out.println("종류 : " + original.getType());

        // 참이슬 클래스에 존재하는 메서드
        original.typeDrink();
    }
}

실행결과는 다음과 같다!!!


2. 인터페이스

인터페이스(Interface)란?

  • 자바에서 인터페이스는 클래스들이 필수로 구현해야 하는 추상 자료형이다.
  • 쉽게 말해, 객체의 사용방법을 가이드라인 하는 것

1) 인터페이스의 필요성

인터페이스를 통해 얻을 수 있는 이점은 다음과 같다.
1. 여러 명이서 작업을 할 때 미리 인터페이스를 작성함으로써 메서드를 정할 수 있다.
2. 상속을 통한 이점을 누릴 수 있다.
3. 개방폐쇄(Open Close)법칙인 확장에는 열려 있고 변경에는 닫혀있는 클래스 간 결합도(코드 종속성)를 낮춘 유연한 방식의 프로그래밍이 가능해진다.

인터페이스는 코드와 인터페이스로 생성된 객체들을 중간에 중계해주는 역할을 한다. 인터페이스로 구현된 객체는 인터페이스에서 정의된 추상 메서드와 동일한 메서드 이름, 매개 타입, 리턴 타입을 가진 실체 메서드를 필수로 가지고 있어야 한다. 이러한 과정을 통해 클래스 간의 결합도(코드 종속성을) 낮춘 효율적인 프로그래밍을 할 수 있다.

Q : 코드 종속성을 낮춘다는 게 무슨 의미인가?

A : 코드 종속성은 각각의 메서드 간의 결합도를 의미하며 인터페이스를 활용하면 한 메서드를 수정하였을 때, 다른 메서드도 수정해야 하는 상황을 줄여준다는 의미이다.


2) 인터페이스 특징

  1. 인터페이스는 메서드 오버라이딩이 필수이기 때문에 다형성이 보장된다.
    • 부모클래스가 인터페이스이면 자식클래스가 무조건 구현되어야 한다.
    • 즉, 부모 인터페이스의 모든 메서들을 자식 클래스에서 반드시 재정의되어야 하기 때문에 다형성이 보장된다.
  2. 다중 상속이 가능하다.
    • 부모가 추상 클래스인 경우와 달리 부모가 인터페이스인 경우 자식 클래스는 인터페이스를 여러 개 상속 받을 수 있음
    public class 클래스명 implements 인터페이스1, 인터페이스2,... { } 
  3. 추상 메서드만 보유한다.
    public abstract final void print() { };
  4. 생성자 생성이 불가능하다.
    • 디폴트 생성자, 인자 있는 생성자 모두 생성이 불가
    • 인터페이스의 멤버 변수는 public static final로만 지정 가능하며 생략 가능
    public static final int value = 100;
    public String str = "s"; // static final 생략 가능

3) 인터페이스 상속 구현

  • 자바에서 인터페이스를 선언할 때는 interface 키워드를 사용한다.
  • interface 키워드를 붙여 인터페이스로 만들게 되면 오직 implements 키워드를 통해 객체들을 구현하는 용도로만 사용 가능

UmcPeople 인터페이스

  • 각 객체들의 말과 행동을 추상 메서드로 가진다.
public interface UmcPeople {
	public static final String name = "UMC 동아리원";
    
    public abstract void saying();
    public abstract void doing();
}

Heron, Jinro, Liu 클래스

  • UmcPeople 인터페이스를 상속한다.
public class Heron implements UmcPeople {
    @Override
    public void saying() {
        System.out.println("헤론 : 나 술 안 마심");
    }

    @Override
    public void doing() {
        System.out.println("헤론 : 인하대 오기");
    }
}

public class Jinro implements UmcPeople {
    @Override
    public void saying() {
        System.out.println("진로 : 폐급 탈출함");
    }

    @Override
    public void doing() {
        System.out.println("진로 : 동방 청소하기");
    }
}

public class Liu implements UmcPeople {
    @Override
    public void saying() {
        System.out.println("리우 : 난 욕 안해");
    }

    @Override
    public void doing() {
        System.out.println("리우 : 짠~");
    }
}

지금까지 만든 인터페이스 상속 예제를 이용하여 출력해보자

public class InterfaceExample {
    public static void main(String[] args) {
        Heron heron = new Heron();
        Jinro jinro = new Jinro();
        Liu liu = new Liu();

        heron.saying();
        heron.doing();

        jinro.saying();
        jinro.doing();

        liu.saying();
        liu.doing();
    }
}

실행결과는 다음과 같다!!!


4) 인터페이스끼리 상속

인터페이스끼리도 상속을 통해 확장을 시킬 수 있고 하위 인터페이스에서 네이밍을 강제하여 객체 간의 통일성을 추구할 수 있다. 인터페이스로 객체를 구현할 때는 implements 키워드를 쓰지만 인터페이스끼리 상속을 할 때는 클래스와 마찬가지로 extends 키워드를 사용


참고자료

8-2. 자바 인터페이스 : 인터페이스 상속, 디폴트 메소드와 인터페이스 확장
JAVA|16.자바의 상속(예제로 쉽게 이해하기
[JAVA] 자바 인터페이스(Interface) 기본 및 활용
[JAVA] 자바 인터페이스(Interface) 사용법 & 예제

profile
초보 개발자의 코딩 일기

1개의 댓글

comment-user-thumbnail
2023년 8월 12일

상속을 잘 정리하셨네용! 참고하겠습니다 ㅎㅎ

답글 달기