Java - interface, abstract class & default method

BK·2024년 7월 10일
0

Java-Basics

목록 보기
5/6
post-thumbnail

Java는 Cpp과 달리 class의 다중 상속을 지원하지 않는다. 다행이다.

Java의 상속

Java는 extends keyword를 통해 class의 상속을 구현할 수 있다.

class ElectronicDevice {
	private String deviceId;
	public void turnOn() {
    	// turn on
    }
}

class Laptop extends ElectronicDevice { }

class AppleWatch extends ElectronicDevice { }

정의된 class와 상속을 통해 여러 class의 관계를 잘 표현할 수 있을 뿐 아니라, 다형성과 같은 OOP의 특징을 활용할 수 있으며, 부모 class에서 정의된 내용을 재사용 할수 있다. 하지만, 위 예시에서 LaptopAppleWatch는 모두 전원을 켜는 turnOn 기능을 가져야 하지만, device별 다른 동작으로 인해 각각 turnOn() 이라는 method를 따로 구현해야 한다. 이처럼 모든 class에서 각자 method를 override 하여 구현해야 하는 상황에서 상위 class에서 method를 구현하는 것은 매우 비효율 적인 작업일 것이다.
이러한 경우, 상위 class에서 해당 method를 아예 작성하지 않도록 할 수도 있지만, 하위 class에서 꼭 구현 되어야 할 turnOn() method가 구현됨을 보장할 수 없다. 이러한 문제를 java의 abstract methodinterface를 통해 해결할 수 있다.

Abstract method

추상 메소드(abstract method)란, 그 구현부가 존재하지 않는 method이다. 아래와 같이 작성할 수 있다.

public abstract class ElectronicDevice {
	private String deviceId;
    
    public abstract void turnOn();
}

기존 method의 구현부인 { }를 지우고, ;을 작성해주면 된다.
Abstract method는 구현부를 가지지 않고, 상속받은 하위 class에서 이를 직접 각자 구현하도록 한다. 그 구현부가 존재하지 않는 method는 호출되면 안되고, 이러한 method를 가지는 class 또한 instance가 되면 안되기에, class에도 abstract keyword를 작성해 주어야 한다.

Abstract class

abstract method를 포함하는 class추상 클래스(abstract class)라고 한다. Abstract class는 오직 상속에만 사용되며, instance가 될 수 없다. 당연하다.
Abstract class는 instance가 될수는 없지만, 다른 instance들을 참조하기 위한 type 으로는 사용될 수 있다.

// invalid
ElectronicDevice device = new ElectronicDevice();
// valid
ElectronicDevice device = new Laptop();

Interface

상위 class에서 method를 직접 구현하지 않는 또다른 방법으로는, interface가 있다.

public interface ElectronicDevice {
	void turnOn();
}

class Laptop implements ElectronicDevice {
	public void turnOn() {
    	// turn on
    }
}

위와 같이 작성할 수 있으며, class의 상속과 달리 implements keyword를 통해 해당 interface에 대한 구현이 이루어 진다.
Interface는 member를 가질 수 있으나, class의 member 변수와 달리 public static final 변수이며, 이를 생략할 수 있다. 또한, method는 모두 구현부를 가지지 않는 abstract method이며, public abstract를 생략하여 작성할 수있다.

Interface의 상속, 구현

Interface의 상속은, interface간 상속과, interface를 구현하는 상속으로 나눌 수 있을것 같다. Interface 자체는 다른 interface를 상속할 수 있으며, extends를 통해 구현할 수 있다. Interface는 abstract method를 가지고 있어, 이를 상속하여 사용하기 위해서는 해당 interface의 method들을 구현해야 한다. 상속 보다 구현이라는 표현이 맞다싶다 implements keyword를 통해 interface를 구현할 수 있으며, 다중 상속을 지원하지 않는 Java이지만, 여러 interface간 다중 상속과 interface들의 다중 구현을 통한 다중 상속은 가능하도록 되어있다.

// interface다중 상속
public interface Laptop extends ElectronicDevice, Computer {
	// sth
}

// class 상속과 interface 구현
public class MyClass extends SomeClass implements Laptop { }

Abstract class vs. Interface

사실 둘 사이에는 많은 문법적인 차이점도 있지만, 가장 큰 차이점은 그 의미가 아닐까 싶다.
Abstract class는 static final이 아닌 member를 가질 수 있고, abstract method가 아닌 method를 가질 수 있는 반면, interface는 static final member 변수만 가질 수 있으며, abstract method만 가질 수 있다.(사실 아니다) 또한 class의 다중 상속은 불가능한 반면, interface는 다중 상속이 가능하며 원하는 class에서 이를 상속/구현 하기 위해 사용하는 keyword 또한 다르다.
하지만, 이러한 문법적인 차이점 외에, 우선 이 둘의 이름에서 부터 차이점이 가장 중요하지 않을까 싶다.
추상 클래스는 어찌 되었든 하나의 class이다. 추상 클래스는 하위 class들을 추상화 하는 것에 의미가 있으며, interface는 이를 구현한 class들이 내부적으로 구현된 방식은 다를 수 있으나 동일한 결과를 보장한다는 하나의 interface, 접점으로서의 의미를 가진다고 생각한다.

abstract class 는 하위 클래스들의 추상화에 의미를 가지며, interface는 구현체들의 동일한 동작 결과를 보장하는 것에 의미를 가진다.

default method

Interface는 abstract method만을 가진다고 했지만, 사실은 아니다. JDK 1.8 부터 interface는 default method를 가질 수 있다. default method구현부를 가지는 interface 내에 존재하는 method이며, 이를 통해 하나의 interface에 method가 추가될 경우 하위 모든 구현 class에서 해당 method를 구현해야 하는 문제를 해결할 수 있다.

method 우선 순위

Java에서 class의 단일 상속만을 지원 하는 경우, 여러 method간 우선순위에 대한 문제는 없겠지만, Interface의 default method로 인해 method간 충돌이 발생할 수 있고, 이를 해결하기 위해 상속/구현한 method간 우선 순위가 존재한다.
최상위 우선순위는 상위 class의 method이며, 이 경우 interface의 default method는 무시된다. 상위 class에 해당 method가 없고, 구현하는 interface들 에서 둘 이상의 동일한 default method가 있는 경우 이를 구현하는 class에서 override하여 충돌을 해결해 주어야 한다.

0개의 댓글