본문 바로가기

개발일기/Java

[Java] Java의 정석 (7) 객체지향개념 4

 

추상 클래스

 

추상 클래스란?

 

- 추상 메소드(선언부만 있고 구현부가 없는 메소드)를 포함하고 있는 클래스

- 추상 클래스는 인스턴스를 생성할 수 없지만, 다른 클래스를 작성하는 데 도움을 준다.

abstract class Player{
    int crtPos;
    
    abstract void play(int pos); // 선언부만 있는 추상 메소드
    abstract void stop();
    
    void play(){
        play(crtPos); // 일반 메소드가 추상 메소드를 사용할 수 있다.
    }
}

 

 

추상 메소드란?

abstract 리턴타입 메소드이름(매개변수);

- 선언부만 있고 구현부가 없는 메소드

- 꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우에 사용한다.

- 추상 클래스를 상속받는 자손 클래스에서 추상 메소드의 구현부를 완성해주어야 한다.

- 이 때, 일부 메소드만 완성해주는 경우에는 그 자손 클래스 역시 추상 클래스로 선언해주어야 한다.

 

 

 

인터페이스

 

 

인터페이스란?

- 일종의 추상 클래스로, 실제 구현된 것이 전혀 없는 기본 설계도이다.

- 추상 메소드와 상수만을 멤버로 가질 수 있다. (상수를 정의할 수 있다는 건 부수적인 것으로, 추상 메소드로만 이루어져 있다고 생각하는 편이 낫다.)

- 인스턴스를 생성할 수 없고, 클래스 작성에 도움을 줄 목적으로 사용된다.

- 미리 정해진 규칙에 맞게 구현하도록 표준을 제시하는 데 사용된다.

 

 

인터페이스의 작성

interface 인터페이스이름{
    public static final 타입 상수이름 = 값;
    public abstract 메소드이름(매개변수);
    // 상수와 추상 메소드만 멤버로 가질 수 있음
}

- 모든 멤버변수는 'public static final' 이어야 하며, 모든 메소드는 'public abstract' 여야 하며, 이를 생략할 수 있다.

 

 

인터페이스의 상속

interface Movable{
    void move(int x, int y);
}

interface Attackable{
    void attack(Unit u);
}

interface Fightable extends Movable, Attackable
{
}

- 인터페이스도 상속이 가능하나, 클래스와 달리 다중상속을 허용한다.

- 인터페이스는 Object 클래스와 같은 최고 조상이 없다.

 

 

인터페이스의 구현

class 클래스이름 implements 인터페이스이름{
    // 인터페이스에 정의된 추상 메소드를 구현
}

class 클래스이름 extends 부모클래스이름 implements 인터페이스이름{
    // 상속과 구현을 동시에 하는 것도 가능하다.
}

- 인터페이스를 클래스에서 구현하는 것은, 인터페이스에 정의된 추상 메소드를 완성해주는 것이다.

- 'extends' 대신 'implements' 를 사용한다.

- 인터페이스에 정의된 추상 메소드의 일부만 구현하는 경우, abstract를 붙여 추상 클래스로 정의해주어야 한다.

 

 

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

- 인터페이스 타입의 변수로 인터페이스를 구현한 클래스의 인스턴스를 참조할 수 있다.

class Fighter extends Unit implements Fightable{
    // 클래스 내용
}

Fighter f1 = new Fighter();
Fightable f2 = new Fighter();
// 인터페이스 타입의 변수로 해당 인터페이스를 구현한 클래스의 인스턴스 참조

 

- 인터페이스를 메소드의 매개변수 타입으로 지정할 수 있다.

void attack(Fightable f){
    // 내용
}
// 인터페이스를 매개변수 타입으로 지정한다는 것은, 
// 그 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 받는다는 것.

 

- 인터페이스를 메소드의 리턴타입으로 지정할 수 있다.

Fightable method(){
    // ...
    return new Fighter()
}
// 인터페이스를 구현한 클래스의 인스턴스를 반환.

 

 

인터페이스의 장점

1. 개발 시간 단축

한 쪽에서는 인터페이스를 작성하고, 한 쪽에서는 인터페이스를 구현하는 클래스를 작성하도록 하여, 양쪽에서 동시에 개발을 진행할 수 있다.

 

2. 표준화가 가능하다

프로젝트에 사용되는 기본 틀을 인터페이스로 작성하면, 개발자들은 그것을 구현하여 일관되고 정형화된 프로그램 개발이 가능해진다.

 

3. 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다

서로 아무런 관계도 없는 클래스들에게 인터페이스를 공통적으로 구현하도록 함으로써 관계를 맺어줄 수 있다. 그러면 다형성의 측면에서 장점을 가지게 된다.

 

4. 독립적인 프로그래밍이 가능하다.

클래스의 선언과 구현을 분리시켜, 클래스와 클래스 간의 관계를 인터페이스를 이용해 간접적인 관계로 변경하면, 한 클래스의 변경이 다른 클래스에 영향을 미치지 않도록 할 수 있다. -> 코드가 유연해짐