[java] 추상클래스 & 인터페이스

송어·2023년 11월 14일

다형성을 보장한다는 것의 의미

다형성을 보장한다는 것의 의미는 부모클래스가 명령을 내리면 자식클래스가 반드시 동작(반응)을 해야 한다는 것이다.
부모클래스의 명령에 자식클래스가 반드시 반응하려면 부모클래스를 재정의(Override)하는 과정이 필수적으로 이루어져야 한다.

하지만 일반적인 클래스 상속 과정에서 재정의는 필수적으로 이루어지지 않기 때문에 다형성이 필수적으로 보장되지는 않는다.

자식클래스가 부모클래스를 반드시 재정의하도록 강제다형성을 보장하기 위해서 추상클래스와 인터페이스가 등장하게 되었다.

추상 클래스(Abstract Class)추상 메서드를 선언하고 상속을 통해 자식크래스에서 메서드를 강제로 완성하도록 유도하는 클래스이다. 이러한 성격 탓에 추상메서드를 불완전한 클래스(미완성 설계도)라고 표현하기도 한다.
추상클래스는 서로 비슷한 클래스의 공통부분을 묶을 때 사용한다.

public abstract class Animal { // 추상클래스(불완전 클래스)
	public abstract void eat(); // 추상메서드(구현부 존재x -> 자식클래스에서 구현부 완성해야함)
}
public class Dog extends Animal {
	
    @Override // 추상클래스 완성
    public void eat() {
		System.out.println("개처럼 먹다");
    }
}

부모클래스가 추상클래스인 경우 접근제어자 다음에 abstract 키워드를 추가해야 한다. 추상메서드는 메서드의 구현부가 없는 메서드로 미완성된 부분은 자식클래스에서 구현을 강제해 다형성을 어느정도 보장하는 것이다.

추상클래스는 단독으로 객체를 생성할 수 없다.(cannot be instantiated)

인터페이스(Interface)

인터페이스는 서로 다른 동작을 가지는 클래스도 상속관계로 만들어서 공통 부분을 동작시킬 때 사용한다.

추상클래스를 사용하는 경우 추상메서드를 자식클래스에서 구현시키는 방식으로 다형성을 보장시킬 수 있다. 하지만 추상클래스는 완전한 구현메서드도 가질 수 있어서 서로 다른 동작을 가지는 클래스의 경우 추상클래스에서 구현한 완전한 메서드가 맞지 않을 수 있다.

// 추상클래스 = 추상메서드 + 구현메서드
public abstract class RemoteControl {

    public abstract void chUp();
    public abstract void chDown();
    public abstract void volUp();
    public abstract void volDown();

    public void internet() { // 구현 메서드
        System.out.println("인터넷이 구동된다.");
    }
}
public class InterfaceTest {
    public static void main(String[] args) {

        System.out.println("------ Radio ------");
        RemoteControl c1 = new Radio();
        c1.chUp();
        c1.chDown();
        c1.volUp();
        c1.volDown();
        c1.internet(); // 구현클래스와 맞지 않는 메서드(오동작)

        System.out.println("------ TV -------");
        RemoteControl c2 = new Tv();
        c2.chUp();
        c2.chDown();
        c2.volUp();
        c2.volDown();
        c2.internet(); // 구현클래스와 맞지 않는 메서드(오동작)
    }
}

RemoteControl class의 internet()메서드는 구현클래스인 Tv와 Radio에는 맞지않는 메서드임에도 동작한다.

이러한 경우를 해결하고 서로 다른 동작을 가지는 클래스도 상속관계로 만들어서 올바른 동작을 시키면서 다형성을 보장할 수 있는 대안으로 인터페이스를 사용한다.

인터페이스(Interface)는 추상클래스와 비슷하지만 구현메서드와 일반 멤버변수를 가질 수 없다. 오직 추상메서드와 static final이 붙은 멤버변수 즉, 상수만 가질 수 있다.
인터페이스는 구현된 게 없는 기본 설계도라고 할 수 있다.
이러한 특징 때문에 추상클래스보다 추상화의 정도가 높아 더 나은 다형성을 보장한다.

인터페이스도 단독으로 객체를 생성할 수 없다.

// 인터페이스 : 추상메서드만 가질 수 있음
public interface RemoteControl {
	
    int MAXCH = 99; // public static final 생략가능
    int MINCH = 1;
    
    void chUp(); // public abstract 생략가능
    void chDown();
    void volUp();
    void volDown();
    void internet();
}
public class InterfaceTest {
    public static void main(String[] args) {

		System.out.println("------ Radio ------");
        RemoteControl c1 = new Radio();
        c1.chUp();
        c1.chDown();
        c1.volUp();
        c1.volDown();
        c1.internet();

        System.out.println("------ TV -------");
        RemoteControl c2 = new Tv();
        c2.chUp();
        c2.chDown();
        c2.volUp();
        c2.volDown();
        c2.internet();
    }
}
<result>
------ Radio ------
라디오 채널 번호 : 48
라디오 채널 번호 : 47
라디오 볼륨 : 40
라디오 볼륨 : 30
Radio에서는 인터넷 지원이 안됨
------ TV -------
TV 채널 번호 : 6
TV 채널 번호 : 5
TV 볼륨 : 25
TV 볼륨 : 20
Tv에서는 인터넷 지원이 안됨

인터페이스를 활용해 서로 다른 기능을 하는 클래스임에도 올바르게 동작하고 있다. 인터페이스를 사용하는 객체는 단순히 인터페이스를 구현한 객체가 되기 때문에 좀 더 유연하게 설계할 수 있게 된다.

인터페이스의 다중상속

일반적으로 Java는 단일상속만 지원하지만 인터페이스의 경우, 다중상속도 지원한다.
인터페이스는 메서드의 구현부가 존재하지 않기 때문에 다중상속을 하는 경우에도 충돌 가능성이 없다.

멤버변수의 경우 기본적으로 static이기 때문에 구현체를 따라가지 않음(독립상수)

  • Dog class가 Animal 클래스를 상속 받고, Pet & Robot Interface를 구현한 경우
public class Dog extends Animal implement Pet, Robot {
// 이하 생략
}

뿐만 아니라, 클래스간 상속처럼 인터페이스 간에도 상속을 통해 확장시킬 수 있다.

public interface B extends A {
// 이하 생략
}
public class C implements B {
// interface B가 A를 상속받았기 때문에 구현체 C는 interface A도 접근 가능
}

인터페이스에 클래스를 상속하는 행위는 불가능하다. 인터페이스는 클래스와는 달리 최고 조상이 Object 클래스가 아니기 때문이다.


Reference

https://code-lab1.tistory.com/287

https://velog.io/@new_wisdom/Java-%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4Interface%EC%9D%98-%EC%A0%95%EC%84%9D-%ED%83%84%ED%83%84%ED%95%98%EA%B2%8C-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC#%EC%9E%90%EB%B0%94%EC%9D%98_%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

0개의 댓글