학습

Interface vs Abstract Class

코동이 2020. 8. 23. 23:59

개요


Interface와 Abstract class는 쓰임새와 모양이 비슷합니다. 이번 기회에 2개의 문법적인 차이가 어떤 것이 있는지 알아보도록 하겠습니다

 

 

Interface 특징


interface PlayingCard {
  public static final int SPADE = 4;
  final int DIAMOND = 3; //항상 앞에 public static final이 붙는다

  public abstract String getCarNumber();
  String getCardKind(); // 항상 앞에 public abstract가 붙는다
  
  default void newMethod() {} // default 메서드
  static void something() {} // static 메서드
}

 

 

- 추상 메서드의 집합이다. ( 왜냐하면 변수도, 생성자도, 가질 수 없기 때문이다! )

- 구현된 것이 없는 설계도. 껍데기이다. ( 모든 접근 제어자가 public이다. )

- 모든 멤버변수는 public static final이 붙는다. ( 부분 생략 가능 )

- 모든 메서드는 public abstract가 붙는다. ( 부분 생략 가능 )

- 추상메서드상수만 멤버로 가질 수 있다.

- implements를 사용하여 구현한다.

 

 

왜 JDK 8버전 부터는 interface 새로운 문법을 추가했을까?


staticdefault를 사용하여 일반 메서드를 구현할 수 있다.

default : implements로 구현하여 다시 내용을 정의 할 수 있다. (안해도 된다)

static   : 객체의 인스턴스로 만들어 사용할 수 없고 PlayingCard.something()로 접근하여 사용한다.

 

기존에는 인터페이스는 추상메서드의 집합이므로 implements로 사용하기 위해서는 모두 구현해주어야 합니다. 하지만 설계 상 중간에 특정 클래스에 메서드가 필요한 경우 추상메서드로 정의되면 모든 하위 자손 클래스들은 불필요한 구현을 해야합니다. 따라서, default와 static을 사용한 메서드가 추가되었습니다.

 

 

왜 extends는 1개만 되고, implements는 여러 개가 될까?


추상 클래스의 extends의 경우, 구현부가 있다. ( 몸통 {} 이 있다.)

인터페이스의 implements의 경우, 구현부가 없다. ( 몸통 {} 이 없다.)

 

즉, 인터페이스는 몸통 구현이 없이 함수명과 매개변수가 있는 선언만 있으므로, 아무리 많은 인터페이스들을 구현해도 내용만 잘 구현하면 된다.

 

 

Abstract Class 특징


abstract class Player {
 abstarct void play(int pos); // 몸통{}이 없는 미완성 메서드
 abstarct void stop();
}

Player p = new Player(); //에러 : 추상클래스의 인스턴스 생성 불가


class AudioPlayer extends Player {
 void play(int pos) {}; // 추상메서드를 구현 몸통 {}
 void stop() {}; // 추상메서드를 구현 몸통 {}
}

 

- abstract이 아닌 일반 메서드를 구현할 수 있다.

extends를 통하여 상속한다.

- static, final, public 뿐만 아니라, 다양한 접근 제어자를 사용할 수 있다.

- 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만들어 사용한다.

 

 

 

기존의 클래스 집합을 추상클래스로 만들기


동물은 나타내는 Dog, Rabbit, Horse 3가지 클래스가 있습니다.

 

class Dog {
 int x, y;
 void move(int x, int y);
 void stop();
 void stimPack()
}

class Rabbit {
 int x, y;
 void move(int x, int y);
 void stop();
 void changeMode();
}

class Horse {
 int x, y;
 void move(int x, int y);
 void stop();
 void load();
}

 

 

추상 클래스 추가


3가지 동물 클래스를 Unit 이라는 추상 클래스를 활용해서 정의합니다.

 

abstract class Unit {
 int x, y, speed;
 abstract void move(int x, int y);
 void stop() {
  this.speed = 0; 
 }
}

class Dog extends Unit {
 //int x, y, speed;
 void move(int x, int y) {};
 //void stop(){};
 void stimPack(){};
}

class Rabbit extends Unit {
 //int x, y, speed;
 void move(int x, int y){};
 //void stop(){};
 void changeMode(){};
}

class Horse extends Unit {
 //int x, y, speed;
 void move(int x, int y){};
 //void stop(){};
 void load(){};
}

 

 

공통점은?


추상메서드를 구현한다는 점은 똑같습니다. interface의 경우 구현하는 클래스가 모든 메서드를 정의하지 않아도 됩니다. implements를 하여도, 일부만 구현하고 abstract 클래스로 만들 수 있습니다.

 

interface Fightable {
 void move(int x, int y);
 void attack(Unit u);
}

abstract class Fighter implemnets Fightable {
 //public void move(int x, int y);
 public void attack(Unit u);
}

 

차이점은?


추상클래스는 일반 클래스에서 "추상 메서드를 추가"로 가지고 있습니다. (멤버변수, 생성자 생성 가능하다)

 

인터페이스는 아무것도 없고 "추상메서드만" 가지고 있습니다. (멤버변수 못가진다, 상수만 가능하다)

또한 인터페이스는 멤버변수를 가질 수 없습니다.

 

 

참고

 

https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

http://tcpschool.com/java/java_polymorphism_abstract

반응형