2023. 12. 13. 15:37ㆍ프로그래밍 언어/Java
1. 추상클래스와 추상메서드
추상클래스란 추상메서드를 포함하는 클래스이다. 추상메서드는 미완성 메서드로 선언부만 작성하고 구현부는 작성하지 않은 메서드이다. 추상클래스와 추상메서드 모두 abstract 키워드로 선언할 수 있고, 상속을 통해 클래스가 완성된다. 추상클래스를 상속받아 클래스를 실제로 구현하고 확장하는 작업을 추상화라고 한다.
추상클래스는 여러 클래스에 공통적인 부분을 뽑아서 추상클래스로 만들어 상속하도록 할 수 있다. 추상클래스를 실제로 사용하는 예시를 보자. 기존 클래스 Marine, Tank, Dorpship의 공통적인 부분을 추상클래스로 만들어서 상속시키는 예제이다.
abstract class Unit{
int x, y;
abstract void move(int x, int y);
void stop(){
//현재 위치에 정지
};
}
class Marine extends Unit{
void move(int x,int y){ /*구현 생략*/ }
void stimPack(){ /*구현 생략*/ }
}
class Tank extends Unit{
void move(int x,int y){ /*구현 생략*/ }
void changeMode(){ /*구현 생략*/ }
}
class Dorpship extends Unit{
void move(int x,int y){ /*구현 생략*/ }
void load(){ /*구현 생략*/ }
}
2. 인터페이스의 구현
인터페이스는 일종의 추상클래스이다. 추상클래스와는 달리 몸통만 갖춘 일반 메서드 또는 멤버 변수를 가질 수 없다. 오직 추상메서드와 상수만을 멤버로 가질 수 있다.
인터페이스는 클래스의 작성과 똑같이 하고 키워드로 class 대신 interface를 사용한다. 그리고 접근제어자로는 public과 default를 사용할 수 있다. 일반적인 클래스와는 다르게 인터페이스는 다음과 같은 제약사항이 있다.
- 모든 멤버변수는 public satic final 이어야 하며, 생략할 수 있다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
인터페이스는 인터페이스로부터만 상속받을 수 있으며, 다중 상속이 허용되고 Object클래스와 같은 최고 조상이 없다.
이런 방식으로 인터페이스를 선언했다면 인터페이스도 추상클래스처럼 상속으로 완성된다. 다만, 인터페이스에서는 상속이 아닌 구현한다는 의미의 키워드 implements를 사용한다. 만약 구현하는 인터페이스의 메서드 중 일부만 구현한다면 abstract를 붙여 추상클래스로 선언해야 하고 상속과 구현을 동시에 할 수 있다. instanceof 연산자의 결과도 상속받은 것과 똑같이 작동한다.
public class Main {
public static void main(String[] args) {
// Fighter의 인스턴스 생성
Fighter f = new Fighter();
// instanceof 연산자를 사용하여 타입 확인
System.out.println("f instanceof Fighter: " + (f instanceof Fighter));
System.out.println("f instanceof Unit: " + (f instanceof Unit));
System.out.println("f instanceof Fightable: " + (f instanceof Fightable));
System.out.println("f instanceof Movable: " + (f instanceof Movable));
System.out.println("f instanceof Attackable: " + (f instanceof Attackable));
System.out.println("f instanceof Object: " + (f instanceof Object));
}
}
interface Movable {
// Movable 인터페이스 내용
}
interface Attackable {
// Attackable 인터페이스 내용
}
interface Fightable extends Movable, Attackable {
// Fightable 인터페이스 내용
}
class Unit {
// Unit 클래스 내용
}
class Fighter extends Unit implements Fightable {
// Fighter 클래스 내용
}
위 예제의 실행 결과는 모두 true로 나온다.
주의할 점이 하나 있는데, 오버라이딩 할 때는 조상의 메서드보다 넓은 범위의 접근 제어자를 지정해야 한다. 따라서 인터페이스를 구현하는 클래스에서 인터페이스의 메서드를 오버라이딩한다면 접근 제어자를 반드시 public으로 해야 한다.
3. 인터페이스를 이용한 다중 상속
인터페이스를 이용하면 다중상속이 가능하다. 하지만 자바에서 인터페이스로 다중상속을 구현하는 경우는 거의 없다. 인터페이스는 static상수만 정의할 수 있으므로 조상클래스의 멤버변수와 충돌하는 경우가 거의 없고, 충돌된다 하더라도 클래스 이름을 붙여 구분할 수 있다. 실제 예시를 보자. Tv 클래스와 VCR 클래스를 동시에 상속받고 싶다면, 둘 중 우선순위가 밀리는 클래스를 인터페이스와 엮어서 사용하면 된다. VCR 클래스를 인터페이스와 엮어서 사용하는 예시를 보자.
// IVCR 인터페이스 정의
interface IVCR {
void play();
void stop();
}
class VCR{
public void play(){
}
public void stop(){
}
}
// Tv 클래스 정의
class Tv {
void turnOn() {
System.out.println("TV is turned on.");
}
void turnOff() {
System.out.println("TV is turned off.");
}
}
// TVCR 클래스 정의, Tv 클래스를 상속받고 IVCR 인터페이스를 구현함
class TVCR extends Tv implements IVCR {
// IVCR 인터페이스의 메서드를 구현
VCR vcr = new VCR();
@Override
public void play() {
vcr.play();
}
@Override
public void stop() {
vcr.stop();
}
}
IVCR인터페이스를 구현하기 위해 새로 메서드를 작성해야하지만, 이처럼 VCR 클래스의 인스턴스를 사용하면 손쉽게 다중상속을 구현할 수 있다.
또한 VCR클래스의 내용이 변경되어도 변경된 내용이 TVCR클래스에도 자동적으로 반영되는 효과도 얻을 수 있다.
사실 인터페이스를 작성하지 않고도 VCR클래스를 TVCR클래스에 포함시키는 것만으로 충분하지만, 바로 뒤에 공부할 다형적 특성을 이용할 수 있다는 장점이 있다.
'프로그래밍 언어 > Java' 카테고리의 다른 글
[JAVA] <자바 기초 完> 예외처리 try-catch-finally 등 (1) | 2023.12.18 |
---|---|
[JAVA] 객체지향 프로그래밍 - 인터페이스를 이용한 다형성 (0) | 2023.12.13 |
[JAVA] 객체지향 프로그래밍 - 다형성의 사용처와 벡터 (0) | 2023.12.06 |
[JAVA] 객체지향 프로그래밍 - 제어자 public부터 abstract까지 (1) | 2023.11.29 |
[JAVA] 객체지향 프로그래밍 - 오버라이딩과 조상 클래스 멤버 지정 - suepr (0) | 2023.11.29 |