추상 클래스 - 미완성 설계도
일반 클래스와 동일하나, 미완성 메서드가 포함된 클래스
abstract class absClass{ //추상 클래스
abstract void absMethod(); //추상 메서드
}
클래스들 간 공통적으로 사용되는 부분을 뽑아 추상클래스로 작성하여, 상속받아 사용할 수 있다.
abstract class Player { // 추상 메서드를 가진 클래스 abstract
// 속성 : 인스턴스 변수 선언 가능
boolean pause; // 일시정지 상태를 저장하기 위한 변수
int currentPos; // 현재 Play 되고 있는 위치 저장하기 위한 변수
// 추상클래스도 생성자 필요!
Player() {
pause = false;
currentPos = 0;
}
abstract void play(int pos); // 추상 메서드 (몸통 {} 블럭이 없음)
abstract void stop(); // 추상 메서드
// 일반 인스턴스 메서드
void play() {
// 메서드는 선언부만 알고 있어도 호출이 가능하다
// 따라서 추상 메서드도 호출이 가능하다
play(currentPos); // 추상 메서드 호출
// 위 추상 메서드를 구현한 클래스의
// 인스턴스를 통해 호출되기 때문에
// 해당 클래스에 구현한 play(int pos)의 구현부가 실행된다.
}
}
아직 구현되지 않은 추상 메서드일지라도, 선언부만 알고 있으면 호출하여 사용할 수 있다.
인터페이스(Interface)
추상메서드의 집합이며, 구현된 것이 전혀 없는 설계도
인터페이스의 속성
- 모든 멤버가 public이고, 상수 이외의 변수는 가질 수 없다.
- 인터페이스만 상속 받을 수 있다.
- 다중 상속이 가능하다.
- 클래스와 달리 최고 조상이 없다.
선언부
interface InterfaceEx{
void move(); // 접근제어자 public 생략
void attack();
}
구현부
abstract class InterfaceTest implements InterfaceEx{
public void move(){
// 생략된 public 접근제어자를 적어주어야 한다.
}
//public void attack(){}
// 구현을 다 하지 못한 클래스는 미완성된 클래스로 취급된다.
}
인터페이스를 이용한 다형성
인터페이스는 이를 구현한 클래스의 조상이라고 할 수 있으므로, 동일하게 해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있다.
일반 다형성과 마찬가지로, interface 안에 있는 메서드들만 사용이 가능하다.
class Fighter extends Unit implements Fightable{
public void move(){}
public void attack(Fightable f){}
}
인터페이스 타입의 매개변수가 갖는 의미는 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야한다는 것이다.
Fightable method(){
Fighter f = new Fighter();
return f;
// 한 문장으로 return new Fighter();
}
리턴타입으로도 인터페이스의 타입을 지정할 수 있는데, 이 때의 이미 역시 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
참조변수의 형변환 속성이 동일하게 적용된다. 해당 속성은 앞 장 '참조변수의 형변환' 에 다루었으니 참고 바란다.
https://9401ndk.tistory.com/32
객체지향 프로그래밍(2) - 다형성
다형성 개념은 클래스와 인터페이스를 활용함에 있어서 가장 중요한 핵심 개념이므로 자세히 알아두어야할 필요가 있다. 다형성(polymorphism) 이란? 여러 가지 형태를 가질 수 있는 능력을 말한다.
9401ndk.tistory.com
인터페이스의 장점
- 개발시간 단축
선언부와 구현부의 분리 ➞ 메서드의 완성을 기다리지 않고도, 선언부만 가지고 작업이 가능하다.
- 표준화 가능
프로젝트 기본 틀을 인터페이스로 작성하고, 개발자들에게 해당 인터페이스를 구현하여 프로그램을 작성하도록 함으로써 정형화된 프로그램 개발이 가능하다.
- 클래스 간의 관계를 맺어줄 수 있다.
상속관계에 있지도 않고, 같은 조상클래스도 가지고 있지 않은 클래스들에게 하나의 인터페이스를 구현하게 함으로써 관계를 맺어줄 수 있다.
- 독립적인 프로그래밍 가능
직접적인 관계(클래스➞ 클래스)에서 간접적인 관계(클래스 ➞ 인터페이스 ➞ 클래스)로 변경하면 한 클래스의 변경이 다른 클래스에 영향을 미치지 않는 독립적인 프로그래밍이 가능하다.
- 중요한 코드를 개발자가 직접 확인하도록 강제할 수 있다.
클래스로 상속받아 사용할 경우, 해당 클래스 내에 사용하지 않는 부분 등 개발자가 직접 확인하지 않고 넘어갈 수 있는 상황이 발생할 수 있다. 인터페이스를 사용하여 해당 부분을 직접 구현하도록 강제할 수 있다.
인터페이스의 이해
class A {
public void methodA(B b){
b.methodB();
}
}
class B {
public void methodB{
System.out.println("methodB()");
}
}
class InterfaceTest{
public static void main(Stirng[] args){
A a = new A();
a.methodA(new B());
}
}
위의 코드에서 클래스 A는 B의 인스턴스를 생성하고, 메서드를 호출한다. 이 경우에는 클래스 A를 작성하기 위해 클래스 B가 이미 작성되어 있어야하며, methodB 선언부가 변경되면 클래스 A도 변경되어야만 한다.
관계도로 나타내면 다음과 같다.
인터페이스를 사용한다면 이러한 직접 연결의 단점을 해결할 수 있다.
interface I {
public abstract void methodB();
}
class A {
public void methodA(I i){
i.methodB();
}
}
class B implements I{
public void methodB(){
System.out.println("methodB in B class");
}
}
class InterfaceTest{
public static void main(Stirng[] args){
A a = new A();
a.methodA(new B());
}
}
인터페이스에 methodB를 정의하고, 클래스 B에서 구현해주었다.
클래스 A는 클래스 B가 아니라 인터페이스 I를 구현한 클래스의 인스턴스를 받아와 사용했다.
이렇게 인터페이스를 이용하면, 만약 클래스 B가 아니라, I를 구현한 클래스 C가 새롭게 들어가게 되더라도 클래스 A를 수정하지 않고 사용할 수 있어 변경에 유리하다.
또한, A 클래스를 작성하는 입장에 있어 B 클래스의 구현을 기다리지 않고, 인터페이스 I의 선언부만 알고 있다면 본인의 코드를 먼저 작성할 수 있어 개발시간을 단축할 수 있다.
'Java > 자바의 정석 3판' 카테고리의 다른 글
객체지향 프로그래밍(2) - 다형성 (0) | 2023.01.25 |
---|---|
객체지향 프로그래밍(2) - 접근 제어자 (0) | 2023.01.25 |
객체지향 프로그래밍(2) - 오버라이딩(Overriding) (0) | 2022.12.26 |
객체지향 프로그래밍(2) - 클래스 간의 관계 설정 (1) | 2022.12.26 |
객체지향 프로그래밍(1) - 변수의 초기화 (0) | 2022.12.24 |