본문 바로가기

JAVA

07장- 객체지향 프로그래밍Ⅱ(6. 추상클래스, 7. 인터페이스) 21. 02. 24.

6. 추상클래스(abstract class)

6.1 추상클래스란?

- 미완성 설계도. 미완성 메서드(추상메서드)를 포함하고 있다는 의미.

- 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상클래스로서 중요한 의미.

-예. 같은 크기의 TV여도 기능 차이에 따라 여러 모델이 있음 -> 이들의 설계도 90%는 동일함 -> 그 공통부분만을 그린 미완성 설계도를 만들어 놓고 이용.

- 키워드 'abstract'. "이 클래스에는 추상메서드가 있으니 상속을 통해 구현해주어야 함."을 의미.

- 추상클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있음.

 

6.2 추상메서드(abstract method)

- 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨둔 것.

- 메서드의 내용이 상속받는 클래스에 따라 달라질 수 있기 때문에, 조상 클래스에는 선언부만을 작성하고, 주석으로 어떤 기능을 위해 작성되었는지 알려 줌.

- 추상메서드는 구현부가 없으므로 괄호{ } 대신 ; 적기.

/* 주석을 통해 어떤 기능을 위해 작성하였는지 설명 */
abstract 리턴타입 메서드이름 ( );

- 추상클래스로부터 상속받는 자손클래스오버라이딩을 통해 조상인 추상클래스의 추상메서드를 모두 구현해주어야 함. 만약, 조상으로부터 상속받은 추상메서드 중 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해 주어야 함.

 

6.3 추상클래스의 작성

- 여러 클래스에 공통적으로 사용될 수 있는 클래스를 바로 작성하기도 하고, 기존의 클래스의 공통적인 부분을 뽑아서 추상클래스로 만들어 상속하도록 하는 경우(추상화)도 있음.

- 상속계층도를 따라 내려 갈수록 세분화되며, 올라갈수록 공통요소만 남게 됨.

 

 

7. 인터페이스(interface)

7.1 인터페이스란?

- 일종의 추상클래스. 추상클래스보다 추상화 정도가 높음.

- 오직 추상메서드와 상수만을 멤버로 가질 수 있음. 

- 다른 클래스를 작성하는데 도움 줄 목서응로 작성됨.

- 추상클래스는 부분적으로만 완성된 '미완성 설계도'라고 하면, 인터페이스는 아무 것도 없고 밑그림ㅁ만 있는 '기본 설계도'

 

7.2 인터페이스의 작성

- 클래스 작성과 같지만 키워드로 class대신 interface 사용.

- 접근제어자 public 또는 decault 사용 가능.

interface 인터페이스이름 {
    public static final 타입 상수이름 = 값;
    public abstract 메서드이름(매개변수목록);
}
- 모든 멤버변수는 public static final 이어야 하며, 생략 가능.
- 모든 메서드는 public abstract이어야 하며, 생략 가능 (static메서드와 디폴트 메서드는 예외 jdk1.8부터)

 

 

7.3 인터페이스의 상속

- 인터페이스는 인터페이스로부터만 상속받을 수 있으며, 클래스와는 달리 다중상속 받는 것이 가능.

 

7.4 인터페이스의 구현

- 자신에 정의된 추상클래스의 몸통을 만들어주는 클래스를 작성.

- 클래스가 extends를 쓴다면 인터페이스를 구현할 땐 implements.

class 클래스 이름 implements 인터페이스이름 {
    // 인터페이스에 정의된 추상메서드를 구현해야 함.
}
class Fighter implements Fightable {
    public void move(int x, int y) {  /* 내용 */ }
    public void attack(Unit u)     {  /* 내용 */ }
}

- 구현하는 인터페이스의 메서드 중 일부만 구현한다면, abstract를 붙여서 추상클래스로 선언해야 함.

- 상속과 구현을 동시에 할 수도 있음.

 

package ex0724;

public class FighterTest {
	public static void main(String[] args) {
		Fighter f = new Fighter();
		
		if(f instanceof Unit) {
			System.out.println("f는 Unit클래스의 자손임.");
		}
		if (f instanceof Fightable) {
			System.out.println("f는 Fightable인터페이스를 구현했음.");
		}
		if (f instanceof Movable) {
			System.out.println("f는 Movable인터페이스를 구현했음.");
		}
		if (f instanceof Attackable) {
			System.out.println("f는 Attackable인터페이스를 구현했음.");
		}
		if (f instanceof Object) {
			System.out.println("f는 Object클래스의 자손임.");
		}
	}
}
class Fighter extends Unit implements Fightable {
	public void move(int x, int y) {}
	public void attack(Unit u) {}
}
class Unit {
	int currentHP; // 유닛의 체력
	int x;		   // 유닛의 위치 (x좌표)
	int y;		   // 유닛의 위치 (y좌표)
	
}
interface Fightable extends Movable, Attackable {}
interface Movable {
	void move(int x, int y);
}
interface Attackable {
	void attack(Unit u);
}

- 아래에서부터 작성. main메서드를 가장 마지막에 작성하는 것임!

- Fighter클래스에서 인터페이스에 정의된 메서드를 구현할 때 접근 제어자를 public으로 했음!!

- 오버라이딩 할 때는 조상의 메서드보다 넓은 범위의 접근 제어자를 지정해야 함.

 

FighterTest.java

7.5 인터페이스를 이용한 다중상속

 

7.6 인터페이스를 이용한 다형성