1. 추상메서드
추상메서드는 구현부 없이 선언부만 존재하는 메서드이다. 다음과 같은 방식으로 사용한다.
abstract 리턴 타입 메서드 이름();
2. 추상클래스
추상 클래스는 추상 메서드를 포함하고 있는 클래스이다. 다음과 같은 방식으로 사용한다.
abstract class 클래스 이름 {}
추상 클래스와 추상 메서드에는 다음과 같은 특징이 있다.
(1) 추상 메서드를 단 하나라도 포함하고 있으면 추상 클래스이다
(2) 추상 클래스는 상속을 통해 자손 클래스로 구현을 완료한 다음, 인스턴스를 생성할 수 있다.
(3) 자손 클래스의 메서드 중에 단 하나라도 구현이 되지 않은 추상 메서드가 있다면 그 자손 역시 추상클래스이다.
(4) 추상 타입 참조변수 = 구현 완료한 자손 타입의 인스턴스
(5) 추상 메서드는 자손 클래스가 필수로 구현해야 하는 메서드이다.
(6) 인스턴스 메서드는 추상 메서드를 호출할 수 있다.
(4)의 예를 들어보겠다. 추상 클래스 Unit의 자손 클래스가 Marine과 Tank라 하고 추상 메서드의 구현이 완료됐다고 하자. 이때 Unit[] u = {new Marine(), new Tank()};라고 하면 참조 변수 u를 통해 Marine과 Tank의 멤버에 접근이 가능하다. 참고로 모든 클래스의 최고 조상인 Object로 배열을 만들어도 되지만 이렇게 되면 Object에는 Marine과 Tank의 멤버가 정의되어 있지 않기 때문에 Object의 참조변수로 접근이 불가하다.
(5)에 설명을 덛붙이자면 지금까지는 조상의 메서드를 자손이 오버라이딩하는 방식을 통해 필요한 메서드를 자손에 맞게 바꾸었다. 하지만 오버라이딩과 달리 추상 메서드를 사용하면 자손이 무조건 구현하도록 강제한다.
3. 인터페이스
인터페이스는 추상클래스보다 더 추상화된 클래스, 추상메서드의 집합이라고 생각하면 된다. 다음과 같은 차이가 있지만 일단은 인터페이스를 추상메서드만을 갖고 있는 클래스라고 알고 있자.
멤버 | 상수 | 생성자 | 추상메서드 | |
추상클래스 | O | O | O | O |
인터페이스 | X (static, 디폴트 메서드 제외) | O | X | O |
인터페이스는 다음과 같이 사용한다.
(public | (default)) interface 인터페이스 이름 {
public static final 타입 상수 이름 = 값;
public abstract 메서드 이름(매개변수 목록);
}
제어자는 전부 또는 일부 생략 가능하다. 인터페이스의 접근 제어자가 public이기 때문에 인터페이스는 클래스의 멤버들에 접근할 수 있는 껍데기 역할을 한다.
[주의] 추상 메서드의 접근 제어자가 public이기 때문에 구현하는 자손의 메서드 접근 제어자 역시 public이어야 한다.
1) 인터페이스의 상속과 구현
인터페이스는 추상 메서드(구현부 없음)만 있기 때문에 다중 상속의 경우에도 충돌이 발생하지 않는다. 따라서 인터페이스끼리의 다중 상속을 허용한다.
클래스(끼리) | 추상 클래스(끼리) | 인터페이스(끼리) | |
다중 상속 허용 | X | X | O |
[참고 1] 인터페이스는 다중 상속을 위한 것이 아니며 실제로 인터페이스를 통해 다중 상속을 하는 경우 또한 거의 없다.
[참고 2] 클래스가 다중 상속을 하는 것은 안되지만 여러 인터페이스를 구현하는 것은 가능하다.
인터페이스의 추상 메서드 완성은 extends 대신에 implements라는 키워드를 사용한다.
추상 메서드의 완성 | |
추상 클래스 | extends (상속) |
인터페이스 | implements (구현) |
[참고 3] 인터페이스의 이름은 주로 ~able로 끝나는 경우가 많은데 어떤 기능을 제공하는 메서드라는 의미를 부여한다.
2) 인터페이스의 특징 (다형성)
인터페이스에는 다음과 같은 특징이 있다.
(1) 상속(extends)과 구현(implements)을 동시에 할 수도 있다.
(2) 인터페이스 또한 구현이 안된 추상 메서드가 하나라도 있을 경우 abstract를 붙인다.
(3) 인터페이스의 추상 메서드의 접근 제어자는 public이므로 구현 시 메서드 또한 public이 되어야 한다.
(4) 매개 변수가 인터페이스 타입일 경우 인자는 인터페이스(추상 메서드)가 구현된 인스턴스 또는 null이다.
(5) 반환 타입이 인터페이스 타입일 경우 인터페이스(추상 메서드)가 구현된 인스턴스의 반환이다.
[예 1]
다음은 (4), (5)를 설명하는 예이다.
class Fighter extends Unit implements Fightable {
public void move (int x, int y) {}
public void attack (Fightable f) {} // (4)
public Fightable getFightable() { // (5)
....
return new Fighter();
}
}
결국 이 또한 다형성의 핵심인 "조상 타입의 참조 변수 = 자손 타입의 인스턴스"가 가능하기 때문이다.
3) static, 디폴트 메서드
인터페이스는 추상 메서드의 집합이지만 허용된 두 가지 다른 메서드가 있다.
(1) static 메서드는 인스턴스의 구현, 생성과 관계가 없기 때문에 인터페이스에 추가해도 문제가 없다.
(2) default 메서드는 인터페이스에만 사용되는 default 제어자가 있고 구현부가 비어있는 메서드라고 생각하면 된다.
(public) default newMethod(){}
인터페이스의 default 메서드는 결국 메서드 간의 충돌을 일으키는데 이때는 그냥 원하는 내용으로 오버라이딩하면 된다.
4. 인터페이스의 장점
단어 interface를 자세히 살펴보면 inter + face로 이루어져 있는데 두 객체 간의 사이에 존재해 둘을 연결하는 역할을 한다고 보면 이해가 쉽다. 예를 들어, 우리가 사용하고 있는 윈도우도 인터페이스의 일종이다. 사용자와 컴퓨터 사이에 존재해 사용자가 원하는 기능을 쉽게 사용할 수 있도록 도와준다.
인터페이스의 장점은 다음과 같다.
(1) 개발 시간을 단축할 수 있다.
(2) 표준화가 가능하다.
(3) 서로 관계 없는 클래스들(형제 관계)에 관계를 부여할 수 있다.
(4) 객체들 간의 느슨한 결합을 만들어줘 변경에 유리한 독립적인 프로그래밍이 가능하다.
(1), (2) 다음 그림을 보면 Java는 JDBC라는 표준을 제공해 두 데이터베이스 사가 개발을 할 때 맞춰야 할 기준을 제공한다. 또한 Java, 두 데이터베이스 사가 개발을 동시에 진행할 수 있어 시간을 단축할 수 있다.
(3) 다음 [그림 2] 노란색 영역의 공통적인 메서드를 구현하고 싶을 때는 각기 다른 타입의 매개변수를 갖는 메서드를 오버로딩 해야 한다. 하지만 인터페이스를 사용하면 타입에 관계 없이 인터페이스를 매개변수로 하는 메서드를 작성하면 된다. 3-2)-(4)를 참고하길 바란다.
(4) 다음의 코드 블럭을 보자. 만약 class B를 class C로 바꾼다면 A의 methodA는 변경할 부분이 없다. 만약 interface I를 사용하지 않는다고 하면 methodB를 갖고 있는 클래스에 따라 methodA의 매개변수의 타입을 바꾸어주어야 할 것이다.
class A {
public void methodA(I i) {
i.methodB();
}
}
interface I { // 껍데기
public abstract void methodB();
}
class B implements I { // 알맹이
public void methodB() {
System.out.println("methodB()");
}
}
Q. 인터페이스란 무엇인가?
A. 추상 메서드의 집합이다.
Q. 인터페이스의 구현이란 무엇인가?
A. 추상 메서드의 구현(구체화)이다.
Q. 추상 클래스와 인터페이스의 공통점과 차이점은 무엇인가?
A. 공통점은 추상 메서드를 갖고 있다는 것이고 차이점은 인스턴스 변수(iv) 가질 수 있냐의 여부(추상 클래스 O, 인터페이스 X)이다.
'자바 (Java) > 요약' 카테고리의 다른 글
Chpt 8. 예외 - 주제 1. 프로그램 오류의 종류 (0) | 2023.11.01 |
---|---|
Chpt 7. 객체 지향 프로그래밍 2 - 주제 6. 내부 클래스 (0) | 2023.10.28 |
Chpt 7. 객체 지향 프로그래밍 2 - 주제 4. 다형성의 장점 2가지 (1) | 2023.10.26 |
Chpt 7. 객체 지향 프로그래밍 2 - 주제 3. 제어자 (0) | 2023.10.26 |
Chpt 7. 객체 지향 프로그래밍 2 - 주제 2. 오버라이딩, 참조변수 super, 생성자 super() (0) | 2023.10.26 |