추상 클래스
추상 클래스(abstract class)는 완전하게 구현되어 있지 않은 메소드를 가지고 있는 클래스를 의미한다.
메소드가 미완성되어 있으므로 추상 클래스로는 객체를 생성할 수 없다.
추상 클래스는 주로 상속 계층에서 추상적인 개념을 나타내기 위한 용도로 사용된다.
자바에서 추상 클래스를 만들기 위해서는 클래스 선언 시에 앞에 abstract를 붙인다.
public abstract class Animal {
public abstract void move(); // 추상 메소드 정의, 세미 콜론(;)으로 종료됨을 유의
...
}
추상 클래스는 하나 이상의 추상 메소드를 가지고 있어야 한다.
추상 메소드는 항상 세미 콜론(;)으로 종료되어야 한다.
추상 클래스를 상속받는 자식 클래스에서는 반드시 추상 메소드를 재정의하여야 한다.
만약 재정의하지 않으면 오류가 발생한다.
public class Lion extends Animal {
// 추상 클래스를 상속받으면 추상 메소드를 구현하여야 한다.
public void move() {
System.out.println("사자의 move() 메소드입니다.");
}
}
추상 클래스의 용도
부모 클래스에서 draw()를 void draw() {} 와 같이 내용이 없는 일반 메소드로 정의한 후에 자식 클래스에서 재정의하는 것과 추상 메소드를 사용하는 방법과는 어떤 차이가 있을까?
결과는 같다.
하지만 추상 메소드로 정의하면 서브 클래스에서는 반드시 구현하여야 하므로 구현을 강요하는 면에서 장점이 있다.
추상 메소드가 아니면 자식 클래스에서 재정의하지 않고 넘어갈 수도 있기 때문이다.
인터페이스
각자의 클래스를 다른 사람의 클래스와 연결하려면 클래스 간의 상호작용을 기술하는 일종의 규격이 있어야 한다. 이러한 규격을 인터페이스(interface)로 정의할 수 있다.
인터페이스 정의
인터페이스를 정의하는 것은 클래스를 정의하는 것과 유사하다. 하지만 키워드 class를 사용하지 않고 키워드 interface를 사용한다.
public interface 인터페이스이름 {
반환형 추상메소드1(...);
반환형 추상메소드2(...);
}
/*
인터페이스는 추상 메소드들과 디폴트 메소드들로 이루어진다.
인터페이스 안에서 필드(변수)는 선언될 수 없다.
상수는 정의할 수 있다.
*/
메소드들은 모두 이름과 매개 변수만 존재하고, 몸체가 없으며 세미콜론으로 종료되는 점에 유의
인터페이스 안에서 선언되는 메소드들은 모두 묵시적으로 public abstract이다.
따라서 public이나 abstract 수식어는 없어도 된다.
인터페이스 구현
인터페이스는 다른 클래스에 의하여 구현(implement)될 수 있다.
인터페이스를 구현한다는 말은 인터페이스에 정의된 추상 메소드의 몸체를 정의한다는 의미이다.
클래스가 인터페이스를 구현하기 위해서는 inplements 키워드를 사용한다.
class Television implements RemoteControl {
...
}
인터페이스 vs 추상 클래스
추상클래스는 바텀 업 : 구체적인 것 만들고 위로
인터페이스는 탑 다운 : 규격 만들고 아래로
추상 클래스는 인터페이스와 유사하다.
이들은 객체화될 수 없고 주로 구현이 안 된 메소드들로 이루어진다.
- 추상 클래스
- 일반적인 필드도 선언할 수 있으며, 일반적인 메소드도 정의할 수 있다.
- 만약 관련된 클래스들 사이에서 코드를 공유하고 싶다면 추상 클래스를 사용하는 것이 좋다.
- 공통적인 필드나 메소드의 수가 많은 경우, 또는 public 이외의 접근 지정자를 사용해야 하는 경우에 추상 클래스를 사용한다.
- 정적이 아닌 필드나 상수가 아닌 필드를 선언하기를 원할 때 사용한다.
- 인터페이스
- 모든 메소드는 public, abstract가 된다.
- 관련 없는 클래스들이 동일한 동작을 구현하기를 원할 때 사용한다.
- 특정한 자료형의 동작을 지정하고 싶지만 누가 구현하든지 신경쓸 필요가 없을 때 사용한다.
- 다중 상속이 필요할 때 사용한다.
인터페이스를 이용한 다중 상속
인터페이스끼리도 상속이 가능하다
인터페이스끼리도 상속이 가능하다.
클래스도 extends를 이용하여 상속을 받을 수 있고
인터페이스도 extends를 이용하여 다른 인터페이스를 상속받을 수 있다.
클래스가 인터페이스를 구현할 때는 implements 키워드를 사용한다.
인터페이스를 이용한 다중 상속
다중 상속(Multiple inheritance)은 하나의 클래스가 여러 개의 부모 클래스를 가지는 것이다.
다중 상속은 애매모호한 상황을 만들 수 있기 때문에 자바에서는 금지되어 있다.
하지만 때에 따라서는 다중 상속이 필요하다.
자바에서는 인터페이스를 이용하여서 다중 상속과 비슷한 효과를 낼 수 있다.
첫 번째 방법은 여러 개의 인터페이스를 동시에 구현하는 것이다.
interface Drivable {
void drive();
}
interface Flyable {
void fly();
}
public class FlyingCar1 implements Drivable, Flyable {
public void drive() {
System.out.println("I'm driving");
}
public void fly() {
System.out.println("I'm flying");
}
public static void main(String[] args) {
FlyingCar1 obj = new FlyingCar1();
obj.drive();
obj.fly();
}
}
두 번째 방법은 하나의 클래스를 상속받고 또 하나의 인터페이스를 구현하는 것이다.
interface Flyable {
void fly();
}
class Car {
int speed;
void setSpeed(int speed) {
this.speed = speed;
}
}
public class FlyingCar2 extends Car implements Flyable {
public void fly() {
System.out.println("I'm flying!");
}
public static void main(String[] args) {
FlyingCar2 obj = new FlyingCar2();
obj.setSpeed(300);
obj.fly();
}
}
상수 정의
인터페이스에는 상수를 정의할 수 있다.
인터페이스에서 정의된 변수는 자동적으로 public static final이 되어서 상수가 된다.
Share article