[Programming] 인터페이스와 추상 클래스의 차이(Difference between interface and abstract class)
Difference between interface and abstract class
인터페이스와 추상 클래스의 차이
추상 클래스와 인터페이스의 차이를 알고 싶어서 스택오버플로를 찾아봤더니 높은 점수를 받은 답변 두 개가 있어서 정리해둔다. 두 답변 모두 읽어보면 추상 클래스와 인터페이스의 차이에 대한 감이 조금 오는 것 같다! 개인적으로 코드는 첫 번째 답변, 설명은 두 번째 답변이 와 닿았다.
(* 오역이 있을 수도 있으니 참고 바랍니다.)
첫 번째 답변 해석본
Interfaces
An interface is a contract: The person writing the interface says, “hey, I accept things looking that way”, and the person using the interface says “OK, the class I write looks that way”.
인터페이스
인터페이스 는 상대방과의 합의다. 인터페이스를 작성하는 사람이 "야, 인터페이스들에 작성된 것 같은 방법(메서드)이면 받아들일게."라고 말할 때, 인터페이스를 사용하는 사람이 "알겠어. 그런 식(메서드)으로 만들게"라고 말하는 것이다.
An interface is an empty shell. There are only the signatures of the methods, which implies that the methods do not have a body. The interface can’t do anything. It’s just a pattern.
인터페이스는 빈 껍데기와 같다. 몸체를 가지지 않고, 메서드의 선언만 존재한다. 인터페이스는 어떠한 것도 수행할 수 없다. 이것은 그저 패턴일 뿐이다.
For example (pseudo code):
// 난 모든 자동차가 이런 모양을 가져야 한다고 말한다.
interface MotorVehicle
{
void run();
int getFuel();
}
// 내 팀원은 차를 아래와 같은 모양으로 작성하고 컴파일 할 것이다.
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
Implementing an interface consumes very little CPU, because it’s not a class, just a bunch of names, and therefore there isn’t any expensive look-up to do. It’s great when it matters, such as in embedded devices.
인터페이스 구현체는 CPU를 아주 조금만 소비한다. 이것은 클래스가 아니라 단순히 이름들의 묶음이기 때문에 살펴봐야 할 것이 없다. 임베디드 기기 같은 것들을 다룰 때 유용하다. (댓글에는 인터페이스의 가치에서 CPU 소비가 중요 포인트 같지는 않다라는 반응도 있었다.)
Abstract classes
Abstract classes, unlike interfaces, are classes. They are more expensive to use, because there is a look-up to do when you inherit from them.
추상 클래스
추상 클래스 는 인터페이스와 다르게 클래스이다. 추상 클래스를 사용하려면 좀 더 비싼 비용을 치른다. 추상 클래스들을 상속받을 때 살펴봐야 할 것들이 존재한다.
Abstract classes look a lot like interfaces, but they have something more: You can define a behavior for them. It’s more about a person saying, “these classes should look like that, and they have that in common, so fill in the blanks!”.
추상 클래스는 인터페이스와 아주 닮았지만 추상 클래스가 몇 가지의 특징을 더 가지고 있다. 추상 클래스에서 행동들을 정의할 수 있다. 이는 마치 "이 클래스들은 이렇게 생겨야 하고, 몇 가지 공통점을 가지고 있다.(상속받는 클래스 입장에서는 추상 메서드라는 공통점만 골라내야 하니까 라는 의미로 보인다.) 그래서 이 빈칸들을 채워야 해!"라고 말하는 것과 같다.
For example:
// 난 모든 자동차가 이런 모양을 가져야 한다고 말한다.
abstract class MotorVehicle
{
int fuel;
// 자동차에 연료는 모두가 필요하다. 그러니까 모두를 위해서 연료를 구현하자.
int getFuel()
{
return this.fuel;
}
// 차가 운행되는 건 달라질 수 있다. 이 부분은 그들 스스로 구현하도록 맡기자.
abstract void run();
}
// 내 팀원은 차를 아래와 같은 모양으로 작성하고 컴파일 할 것이다.
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
Implementation
While abstract classes and interfaces are supposed to be different concepts, the implementations make that statement sometimes untrue. Sometimes, they are not even what you think they are.
구현
추상 클래스와 인터페이스가 개념적으로 달라보이지만, 구현을 할 경우 사실과는 좀 다르다. 가끔은 이들의 경계가 모호할 때도 있다.
두 번째 답변 해석본
Abstract classes can have constants, members, method stubs (methods without a body) and defined methods, whereas interfaces can only have constants and methods stubs.
Methods and members of an abstract class can be defined with any visibility, whereas all methods of an interface must be defined as public (they are defined public by default).
When inheriting an abstract class, a concrete child class must define the abstract methods, whereas an abstract class can extend another abstract class and abstract methods from the parent class don’t have to be defined.
Similarly, an interface extending another interface is not responsible for implementing methods from the parent interface. This is because interfaces cannot define any implementation.
A child class can only extend a single class (abstract or concrete), whereas an interface can extend or a class can implement multiple other interfaces.
A child class can define abstract methods with the same or less restrictive visibility, whereas a class implementing an interface must define the methods with the exact same visibility (public)
표로 정리.
인터페이스 | 추상 클래스 |
---|---|
상수와 메서드 스텁만 가진다. | 상수, 멤버변수, 메서드 스텁를 가질 수 있고, 메서드를 정의할 수 있다. |
모든 메서드의 접근자는 오직 public뿐이다. | 추상 클래스의 메서드나 멤버변수들은 아무 접근자든 정의할 수 있다. |
인터페이스가 다른 인터페이스를 상속 받을 경우, 부모 인터페이스의 메서드를 구현할 책임은 없다. 왜냐면 인터페이스는 어떤 구현도 할 수 없기 때문이다. 구체적인 클래스가 인터페이스를 상속받으면 무조건 인터페이스의 메서드를 정의해야 한다. | 추상 클래스를 상속받을 경우, 구체적인 자식 클래스는 추상 메서드를 무조건 정의해야 한다. 반면에, 추상 클래스는 다른 추상 클래스를 상속받았을 때는 추상 메서드나 클래스를 정의할 필요는 없다. |
자식 클래 스가 복수개의 인터페이스를 상속받는 것이 가능하다. | 자식 클래스가 오직 하나의 클래스만 상속받을 수 있다.(추상 클래스든 구체적 클래스든) |
자식 클래스는 부모 인터페이스 메서드의 접근자와 동일하게만 정의할 수 있다.(오직 public만) | 자식 클래스는 부모 추상 클래스의 메서드 접근자와 같거나 더 제한적으로 정의할 수 있다. |
출처: StackOverFlow