반응형

추상클래스란?

1. 추상 메소드와 완성된 메소드로 구성되어 있는 클래스.
 
2. 추상 메소드(Abstract Method)선언부만 존재하며, 구현부 {}는 존재하지 않는다.
 
3. 만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면, 상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다.
 
4. 추상 클래스를 상속받은 클래스는 추상 클래스에 있는 추상 메소드를 구현해줘야한다. 단, 상속 받은 클래스가 추상 클래스일 경우에는 모든 추상 메소드를 구현하지 않아도 된다.

우선 첫 번쨰와 두 번째 정의를 살펴보자.

 

1. 추상 메소드와 완성된 메소드로 구성되어 있는 클래스.

2. 추상 메소드(Abstract Method)는 선언부만 존재하며구현부 {}는 존재하지 않는다.

초록색 네모 안에는 class 앞에 abstract를 사용하여 추상 클래스임을 확인할 수 있다.

빨간색 네모 안에 있는 abstract void move(int x, int y);는 여타 메소드와는 다르게 구현부 {}, 중괄호로 되어 있는 부분이 없다. 이런 메소드를 추상 메소드라고 불리며, 껍데기만 있다고 표현할 수 있다.

검은 네모 안에 있는 메소드는 흔히 볼 수 있는 메소드이다. 선언부에 void stop()이 있고, 구현부에는 값을 출력하는 것을 보이고 있다.

이처럼 추상 클래스는 클래스 내에 추상 메소드, 일반 메소드가 모두 존재할 수 있다. 하지만, 인터페이스는 무조건 추상 메소드만 있어야 한다는 것이 추상 클래스와의 차이점이다.

 

3. 만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다.

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){
        System.out.println("Marine[ x = " + x + ", y = " + y + "]");
    }
}

class Tank extends Unit {
    void move(int x, int y){
        System.out.println("Tank[ x = " + x + ", y = " + y + "]");
    }
}   

class Dropship extends Unit {
    void move(int x, int y) {
        System.out.println("Dropship[ x = " + x + ", y = " + y + "]");
    }
}

public class Abstract3 {
    public static void main(String args[]){
//      Unit[] group = {new Marine(), new Dropship(), new Tank()}; 아래 세 줄을 한 줄로 줄인 것   // 추상 클래스 객체를 만드는 건 불가능. 왜냐면 추상 클래스에는 추상 메서드가 있을 수 있기 때문. 그래서 상속받은 클래스 형으로 객체를 생성해야 함.
        Unit[] group = new Unit[3];
        group[0] = new Marine();
        group[1] = new Dropship();
        group[2] = new Tank();
    
        group[0].move(100, 200);
        group[1].move(100, 200);
        group[2].move(100, 200);

    }
}

 

우측이 추상 클래스, 좌측이 추상 클래스를 상속받은 Marine, Tank, Dropship 클래스

Unit 이라는 추상 클래스를 상속 받은 Marine, Tank, Dropship 클래스들은 추상 메서드인 abstract void move(int x, int y);를 구현(완성)하고 있는 것을 확인할 수 있다. 만약 Unit 추상 클래스를 상속받은 일반 클래스에서, move 메서드를 구현하지 않았다면 컴파일러에서 에러를 발견하여 빨간 줄이 뜨는 걸 볼 수 있다. 이렇게 추상 매서드를 구현해야 main에서 Unit 객체를 생성할 수 있다.

 

이렇듯, 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만들 수 있다.

 

(참고, Marine, Tank, Dropship 객체를 생성하되 참조변수는 Unit 으로 선언할 수 있다. 왜냐하면 상속 받았기 때문!

 

ex) Unit[] group = new Unit[3]; 

Unit[] group = new Marine[3];

Unit[] group = new Tank[3];

Unit[] group = new Dropship[3] ;

 

하지만 Marine 객체를 선언하면 Marine 클래스 내에 있는 메소드와 상속 받은 Unit 클래스 내에 있는 메소드만 사용 가능하다. 나머지도 동일!)

 

4. 추상 클래스를 상속받은 클래스는 추상 클래스에 있는 추상 메소드를 구현해줘야한다. 단, 상속 받은 클래스가 추상 클래스일 경우에는 모든 추상 메소드를 구현하지 않아도 된다.

 

이게 무슨 뜻인지 아래 코드를 보며 이해해보자.

 

좌측이 추상 클래스, 우측이 Marine 클래스

추상 클래스 Unit에는 세 가지의 메서드가 있다.

abstact void move, abstract void fly, void stop.

 

<만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다>라는 3번의 정의에 따르면,  현재 Marine 클래스에는 move 메서드는 구현했지만 fly 메서드는 구현하지 않았다. 그래서 빨간 줄이 나오는 것을 볼 수 있다. 

 

하지만, 여기서 Marine 클래스를 추상 클래스로 선언한다면, 굳이 모든 추상 메서드를 구현할 필요가 없어진다.

반응형

+ Recent posts