Hun's Blog

[JAVA] abstract와 interface의 차이점 본문

Language/Kotlin & Java

[JAVA] abstract와 interface의 차이점

jhk-im 2020. 3. 21. 23:06

추상 메소드 (abstract method)


자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드를 의미한다.
자바에서 추상 메소드를 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식클래스가 반드시 추상 메소드를 구현하도록 하기 위함이다.

모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 쉬워지기 때문이다.

추상 메소드는 선언부만 존재하며, 구현부는 작성되어 있지 않다.
이 작성되어 있지 않은 구현부를 자식 클래스에서 오버라이딩 하여 사용하는 것이다.

 

추상 클래스(abstract class)


자바에서 하나 이상의 추상 메소드를 포함하는 클래스를 추상 클래스라고 한다.
이러한 추상 클래스는 객체 지향 프로그래밍에서 중요한 특징인 다형성을 가지는 메소드의 집합을 정의할 수 있도록 해준다. 반드시 사용되어야 하는 메소드를 추상 클래스에 추상 메소드로 선언해 놓으면, 이 클래스를 상속받는 모든 클래스에서는 이 추상 메소드를 반드시 재정의해야 한다.

추상 클래스는 동작이 정의되어있지 않은 추상메소드를 포함하고 있으므로 인스턴스를 생성할 수 없다. 먼저 상속을 통해 자식 클래스를 만들고, 만든 자식 클래스에서 추상 클래스의 모든 추상 메소드를 오버라이딩하고 나서 자식클래스의 인스턴스를 생성할 수 있게 된다.

추상 클래스는 추상 메소드를 포함하고 있다는 점을 제외하면, 일반 클래스와 모든 점이 같다. 생성자와 필드, 일반 메소드도 포함할 수 있다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
abstract class Animal {
    abstract void cry();
}
class Cat extends Animal {
    @Override
    void cry() {
        System.out.println("냐옹");
    }
}
class Dog extends Animal{
    @Override
    void cry() {
        System.out.println("멍멍");
    }
}
 
 
//호출 및 결과
Cat c = new Cat();
Dog d = new Dog();
c.cry(); // 냐옹
d.cry(); // 멍멍
 

 

추상 클래스인 Animal 클래스는 추상 메소드인 cry() 메소드를 가지고있다. Animal 클래스를 상속받는 자식 클래스인 Dog 클래스와 Cat 클래스는 cry() 메소드를 오버라이딩 해야만 비로소 인스턴스를 생성할 수 있다.


추상 메소드 사용목적 


추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함이다. 일반 메소드로 구현한다면 사용자에 따라 해당 메소드를 구현할 수도 안할 수도 있다. 하지만 추상 메소드가 포함된 클래스를 상속받은 모든 자식 클래스는 추상 메소드를 구현해야만 인스턴스를 생성할 수 있으므로 반드시 구현하게 된다.

정리 - 

추상 클래스는 추상 메소드를 포함한 클래스이다. 추상 클래스를 상속받는 자식 클래스들은 반드시 추상메소드를 오버라이딩 해야만 인스턴스를 생성할 수 있다. 자식 클래스에서 메소드를 강제로 구현하도록 한다는 것이다. 인터페이스랑 너무 비슷해서 사실 아직까지는 무슨 차이인지를 모르겠다.  인터페이스도 다시한번 살펴보고 둘의 차이에 대해 알아보자. 

인터페이스 (interface)


클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러가지 문제가 발생할 수 있기 때문에 자바에서는 클래스를 통한 다중 상속은 지원하지 않는다. 다중 상속의 이점을 버릴 수는 없기에 자바에서는 인터페이스를 통해 다중 상속을 지원하고 있다.

인터페이스란 다른 클래스를 작성할 때 기본이 되는 틀을 제공 하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미한다.

추상 클래스는 추상 메소드 뿐만 아니라 생성자, 필드, 일반 메소드도 포함할 수 있다.
하지만 인터페이스는 오로지 추상 메소드와 상수만을 포함할 수 있다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interface Animal {
    void cry();
}
class Cat implements Animal{
    @Override
    public void cry() {
        System.out.println("냐옹");
    }
}
class Dog implements Animal{
    @Override
    public void cry() {
        System.out.println("멍멍");
    }
}
 
호출 및 결과 
Cat c = new Cat();
Dog d = new Dog();
c.cry(); // 냐옹
d.cry(); // 멍멍
 

abstract와 다른 점은 extends대신 implements를 사용했다는 것과 interface 내부의 메소드는 abstract로 선언하지 않았다는 것이다.  다중 상속을 지원하기 위해 인터페이스가 존재한다고 하니 다중 상속예제를 보도록 하자. 

다중상속예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
interface Animal {
    void cry();
}
interface Pet {
    void play();
}
class Cat implements Animal,Pet{
    @Override
    public void cry() {
        System.out.println("냐옹");
    }
    @Override
    public void play() {
        System.out.println("쥐잡기");
    }
}
class Dog implements Animal,Pet{
    @Override
    public void cry() {
        System.out.println("멍멍");
    }
    @Override
    public void play() {
        System.out.println("산책하기");
    }
}
 
호출 및 결과
Cat c = new Cat();
Dog d = new Dog();
c.cry(); // 냐옹
c.play(); // 쥐잡기
d.cry(); // 멍멍
d.play(); // 산책하기
 

 

Pet 이라는 인터페이스가 추가 되었고 Animal과 Pet 인터페이스를 동시에 상속받고있다. 당연한 것이지만 abstract를 위와같이 다중상속으로 구현하면 에러가 발생한다. 인터페이스는 다중상속을 위해 존재한다는 점 기억해두자. 

인터페이스의 장점
1. 다중상속 가능
2. 대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화 가능
3. 클래스 작성과 인터페이스 구현을 동시에 하므로 개발시간 단축
4. 클래스와 클래스 간의 관계를 인터페이스로 연결하면, 클래스마다 독립적인 프로그래밍이 가능하다.

abstract와 interface의 주요 차이점이 다중상속 이라는 것을 알게되었다. 허나 항상 두가지의 차이점을 비교하다보면 항상 왜 더 좋은 쪽을 쓰면되지 일부 지원을 하지않는 기능이 있는 것일까? 하는 의문이 들기마련이다. 역시나 지금까지의 결과로는 인터페이스를 사용하는게 더 현명하다는 생각밖에 안들기 때문에 내부 동작과정중 어떠한 차이가있고 어떤 이점이 있는지를 구글링을 통해 찾아보았다. 

인터페이스와 추상 클래스는 존재 목적이 다르다? 
추상클래스의 존재 목적은 추상클래스를 상속받아서 기능을 이용하고 확장시키는 데 있다.
인터페이스의 존재 목적은 함수의 껍데기만 가지고 있으면서 함수의 구현을 강제하고 결과적으로 구현 객체의 같은 동작을 보장하기 위함이다.


디테일한 차이점

추상클래스
- 추상 메소드가 반드시 한개 이상 포함
- 일반 메소드, 일반 변수, 생성자를 포함할 수 있음
- 추상클래스 간 상속가능
  ->오버라이드 하지 않고 그대로 둘 수 있음
- 인스턴스를 만들 수 없고 상속받은 클래스를 통해 인스턴스화 가능
- 접근지정자는 어떤 것이든 가능
- 클래스이므로 상속 시 extends를 사용
* 궁극적인 목적은 상속하기 위함이다.
* 필요에 의해서 일반 메소드와 더불어 추상화 기능을 가미할 때 사용한다.


인터페이스
- 클래스가 아니다.
- 비어있는 추상 메소드만 포함
- 메소드에 final을 붙일 수 없고 변수는 모두 static 이어야 함
- 일반변수와 일반메소드, 생성자를 포함할 수 없음
- 인스턴스를 만들 수 없고 상속받은 클래스를 통해 인스턴스 화 가능
- 접근지정자는 없거나 public, abstract 만 가능
- 인터페이스간 상속 가능
  -> 내용이 없는 메소드를 상속받는 것이고 구현이 아니므로 extends를 사용한다.
- 클래스가 아니므로 상속시 implements를 사용한다.
* 인터페이스는 메소드들의 집합이다.
* 변수앞에 static final 이나 메소드앞에 abstract 명령어를 안써도 자동인식한다.
   -> 가독성을 위해서라면 생략 가능한 부호는 항상 쓰는것이 바람직하다.
* 한눈에 보면 빈껍데기 뿐이라서 한눈에 들어오므로 사용빈도가 높다.


속도
추상 클래스가 인터페이스보다 속도가 빠르다.
인터페이스는 관련 메소드들을 찾기 위해 부가적인 일들을 더 처리한다.

상황에 따른 구분
1. 추상 메소드만 선언한다면 인터페이스를 ,
다른 일반 메소드나 필드도 필요하면 추상클래스를 사용한다.

2. 같은 종류나 행동들을 구현할 것이 많을 때 -> 추상클래스

3. 상속에 대한 계층구조를 명확히 표현하고자 한다면 -> 추상클래스

4. 디자인을 구성하는 요소들이 자주 바뀔때 -> 인터페이스

5. 클래스 전체가 아닌 메소드들만 쓰고싶을 때 -> 인터페이스


정리 - 
앞서 추상클래스와 인터페이스의 가장 큰 차이점은 다중상속 이었다. 그래서 인터페이스는 다중상속을 위해 존재한다라고 가정했었는데 그것 보다는 각자의 존재 목적을 명확히 구분해서 설명하는 편이 이해하는데 있어서도 설명하는데 있어서도 더 중요한 것 같다. 

먼저 인터페이스의 존재 목적을 보면 추상메소드의 집합으로 이를 상속받는 자식 클래스의 객체가 같은 동작을 하도록 보장한다는 것에 있다. 다중상속의 개념은 그것을 더 효과적으로 하기위해 따라오는 것이라 새겨두고 설명하도록 하자. 

추상클래스는 상속받은 자식 클래스가 추상클래스의 기능을 사용하고 확장시키는데에 있다. 사실 추상클래스를 많이 다뤄보지 않았고 예제로도 접한 기억이 별로없다. 아님 몰랐거나. 인터페이스보다는 이해가 좀 떨어지는게 사실이다. 그나마 가장 눈에 들어왔던 것은 상속에 대한 계층 구조를 명확히 표현할 수 있다는 것이다. 조금 답답해서 몇개 더 찾아 보았는데 좀더 도움 될만한 설명을 발견하였다.

'객체지향설계 개념을 익히면 추상 클래스와 메서드의 개념을 이해하기 쉬워진다' 

객체지향에 관련된 내용은 다시한번 깊게 공부해 봐야 할 내용이다. 일단은 지금의 추상클래스의 개념을 적립해 둔 상태에서 객체지향설계에 대해서 정리할 때 시야를 넓혀보는 방향으로 .. 

인터페이스 같은 경우는 안드로이드에서 mvp, mvvm 패턴을 공부할 때 많이 사용했기 때문에 조금더 이해가 잘 되었던 것 같다.  이 또한 다시한번 정리해야하기 때문에 동일하게 그때 다시 시야를 넓혀보도록 하자.  


  

http://alecture.blogspot.com/2011/05/abstract-class-interface.html
https://brunch.co.kr/@kd4/6
http://tcpschool.com/java/java_polymorphism_interface
http://tcpschool.com/java/java_polymorphism_abstract

 

자바의 추상 클래스와 인터페이스

추상 클래스와 인터페이스의 차이 | 추상 클래스(Abstract class)와 인터페이스(Interface)의 차이 및 존재 이유를 설명해주세요. 클래스는 크게 일반 클래스와 추상 클래스로 나뉘는데 추상 클래스는 클래스 내 '추상 메소드'가 하나 이상 포함되거나 abstract로 정의된 경우를 말합니다. 반면 인터페이스는 모든 메소드가 추상 메소드인 경우입니다. (자바 8에서는 default

brunch.co.kr

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 

자바의 추상클래스(abstract class)와 인터페이스(interface)

자바의 상속 개념을 공부할때 빠지지 않고 등장하는 것이 바로 오늘 배울 추상클래스(abstract class)와 인터페이스(interface)다. 무슨 공통점이 있는지 무슨 차이점이 있는지 말도 애매모호하고 서로 비슷비슷하므로 이 부분만 나오면 ...

alecture.blogspot.com