기존 클래스가 완성된 하나의 설계도라면 추상 클래스는 완성되지 못한 설계도라고 할 수 있다. 여기서 그럼 왜 완성된 설계도를 사용하면 되지 미완성된 설계도가 필요하냐 물어볼 수도 있는데. 미완성된 설계도로 틀을 만들어 여러 설계도를 완성시키는데 활용할 수 있다.
abstract class 클래스 이름{}
와 같이 선언하며 내부에는 멤버 변수와 메서드를 가질 수 있다. 또한 메서드의 경우 추상 메서드를 가지는데
추상 메서드 또한 추상 클래스와 같은 의미로 미완성된 메서드라고 생각하면 된다.
public class Test {
public static void main(String[] args){
Terran terran = new Terran();
Unit marine = terran.createUnit(100, 1);
Zerg zerg = new Zerg();
Unit zergling = zerg.createUnit(50, 1);
}
}
abstract class Unit{
int hp;
int attack;
abstract Unit createUnit(int hp, int attack);
}
class Terran extends Unit{
@Override
Unit createUnit(int hp, int attack) {
return new Terran();
}
}
class Zerg extends Unit{
@Override
Unit createUnit(int hp, int attack) {
return new Zerg();
}
}
위와 같이 미리 Unit이라는 class를 완성하지 않은 설계를 통해 Terran과 Zerg class를 생성할 때 createUnit 메서드는 무조건 설계해야하도록 강제성을 만들 수 있다. 이를 통해 개발자는 추상 클래스에 상속받을 자손 클래스들이 무조건 구현해야할 메서드들을 정해줄 수 있고 추상 클래스를 상속 받은 자손 클래스는 자신이 어떤 메서드를 구현해야할지 바로 알 수 있다.
인터페이스도 일종의 추상 클래스이다. 하지만 추상 클래스보다 추상화 정도가 더 높아서 멤버 변수와 완성된 메서드가 일체 사용할 수 없다. 추상 클래스를 부분적으로만 완성된 미완성 설계도
였다면 인터페이스는 구현된 것은 아무 것도 없고 밑그림만 그려져 있는 기본 설계도
라 할 수 있다.
interface 인터페이스_이름{
public static final 상수;
public abstract 반환_타입 메서드_이름();
}
다음과 같이 인터페이스를 작성해야한다. class 대신 interface를 사용하며 멤버변수는 정의하지 못하고 상수만 정의할 수 있다. 또한 public static final만 사용 가능하며 생략 가능하다. 메서드도 마찬가지로 public abstract만 사용이 가능하며 생략 가능하다.
인터페이스는 class의 extends가 아닌 implements로 상속을 받는다. 그리고 인터페이스는 java에서 유일하게 다중 상속이 가능한데. 중요한 점
은 다중 상속이 가능한 것이지 인터페이스가 다중 상속을 위해 만들어진 것이 아니란 것이다. java에서는 다중 상속을 권장하지 않는 편인거 같다. 또한 class가 extends로 다른 class를 상속 받고 추가로 인터페이스를 상속 받는 것도 가능하다.
인터페이스를 이용하여 java의 다형성을 구현할 수 있는데. 추상 클래스와 같이 형변환을 하는 것에 사용될 수 있으며, 매개변수로 인터페이스를 받을 수도 있다. 하지만 여기서 중요한 것은 리턴 타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환하는 것을 의미
라는 것이다.
인터페이스를 사용하는 이유
지금까지 인터페이스에 대해 알아봤는데 아직 정확히 왜 인터페이스를 사용해야하는지 모르겠고 오히려 다중 상속을 위해 사용된다고 생각할 수도 있다. 물론 위에 말한것처럼 다중 상속을 위해 인터페이스가 생긴 것은 아니다! 그럼 진짜 java는 왜 인터페이스를 만들었을까?
인터페이스에서는 두 가지를 항상 기억하자
즉 위 내용을 가능하게 해주는 것이 인터페이스이고 인터페이스를 통해 개발자는 선언과 구현을 분리하여 진행할 수 있게 되는 방법으로써 사용할 수 있다. 인터페이스는 java에서 자체적으로 선언만 할 수 있게끔 강하게 정의되어 있는 부분이므로 구현 자체를 할 수 없다. 또한 인터페이스를 상속받은 class는 강제적으로 선언되어진 메서드를 구현해야만 한다. 이를 혼자서 개발하는 프로그램이라면 굳이? 라는 물음이 있겠지만 적어도 개발자 2명 이상이 모인다면 서로 이 부분을 분리하여 개발을 진행할 수 있을 것이다.