Java/Grammer

추상클래스와 인터페이스의 차이

2022. 1. 16. 00:54

( 2022.05.15 수정 - 내용 추가와 글 서식 변경 )

 

자바8에서 람다에 대한 내용이 추가됨에 따라 인터페이스에서 메서드를 구현할수 있게되었습니다.

이전에는 추상클래스와 인터페이스의 주요 차이점은 구현과 상속이었습니다.

하지만 이제 구현까지 인터페이스에서 가능해짐에 따라 이 둘의 경계가 모호해졌습니다.

그렇다면 차이점은 무엇일까요?

 

 

인터페이스와 추상메서드의 공통점

dafult 키워드를 사용하면 인터페이스 안에서 필드 사용메서드를 구현할 수 있게 되었습니다.

public interface HelloInterface {
	String text = "hello";
	
	default void sayHello() {
		System.out.println(text);
	}
}

public class People implements HelloInterface{
    public static void main(String[] args) {
        People people = new People();
        people.sayHello();   //hello
    }
}

 

하지만 이는 추상메서드와 동일한 것은 아닙니다. 인터페이스에서는 생략된 키워드들이 많이 있기 때문이죠.

먼저 필드의 경우 static fianl 키워드가 생략되어 있습니다. 메서드의 경우 자바8 이전과 같이 public abstract가 생략되어 있죠.

자 그럼 확인해볼까요?

public interface HelloInterface {
	String text = "hello";
	
	void sayHi();
	
	default void sayHello() {
		System.out.println(text);   //정적 멤버변수 text 사용
	}
}

public class People implements HelloInterface{
    @Override
    public void sayHi() {
        System.out.println("hi");
    }

    public static void main(String[] args) {
        People people = new People();
        people.sayHello();   //hello
        people.sayHi();      //hi
    }
}

보시다시피 해당 인터페이스를 구현하면 인터페이스에서 선언한 정적 멤버변수인 text를 사용할수 있다는 것을 확인하실 수 있습니다.

 

이를 추상메서드로 똑같이 표현하면 다음과 같습니다.

public abstract class HelloAbstract {
	public final static String text = "hello";
	
	public abstract void sayHi();
	
	public void sayHello() {
		System.out.println(text);
	}
}

public interface HelloInterface {
	String text = "hello";
	
	void sayHi();
	
	default void sayHello() {
		System.out.println(text);
	}
}

 

인터페이스에선 정적 멤버변수만 사용가능하며 일반적인 멤버변수는 사용할 수 없습니다.

그렇다면 이게 끝일까요?

 

추상클래스와 인터페이스의 차이점

그럴리가 없죠. 가장 중요한 차이점은 바로 다중상속입니다.

저는 개발자이면서 게임도 좋아하는 게이머이기도 합니다. 이 상황을 추상 클래스로 구현이 가능할까요? 설사 구현이 가능하더라도 매우 지저분해질거란건 대충 예상이 되실겁니다.

인터페이스를 사용하면 아주 간단하게 해결할 수 있습니다. 인터페이스는 다중상속이 가능하닌까요!

public interface Developer {
	default void programming() {
		System.out.println("I'm programming");
	}
}

public interface Gamer {
	default void playGame() {
		System.out.println("I'm playing game");
	}
}

public class People implements Developer, Gamer{
	public static void main(String[] args) {
		People me = new People();
		me.playGame();      //I'm playing game
		me.programming();   //I'm programming
	}
}