Java Abstract 클래스

Bennie97·2022년 1월 24일
0

Java의 추상클래스에 대해서 알아보자

class Vehicle{
    private int posX, posY;
	
    public void move(int posX, int posY){
    	System.out.printf("%X, %Y로 이동%n", posX, posY);
    }
    
    public void stop() {
    	System.out.println("멈춰");
    }
    
    public void refuel() {
    	System.out.println("주유한다");	
    }
}

class Car extends Vehicle{
	public void refuel(){
    	System.out.println("가솔린을 넣습니다");
    }
}

class ElectricCar extends Vehicle{
	public void refuel(){
    	System.out.println("전기를 충전합니다.");
    }
}

위와 같은 코드가 있다고 가정하자
Vehicle이라는 부모 클래스를 Car와 ElectircCar가 상속받는다.
refuel 메소드는 오버라이딩 하는 모습을 볼 수 있다.

이 상황에서 우리는

public class Test {
	public static void main(String[] args) {
		Vehicle [] vec = {new Car(), new ElectricCar()};
	    
	    for(int i = 0; i < vec.length; i++) {
	    	int posX = (int)(Math.random()*10) + 1;
	    	int posY = (int)(Math.random()*10) + 1;

	    	vec[i].move(posX, posY);
	    	vec[i].refuel();
	    	vec[i].stop();
	    	
	    	
	    }
	}

}

이런식으로 사용할 수 있을것이다.

그러나.. 한가지 의문이 생긴다..
Vehicle 클래스의 refuel메소드는 정작 사용하지 않고
클래스 ElectricCar, Car 등에서 상속받아 사용한다는 것이다.

이런 상황에서 굳이 부모클래스인 Vehicle에 refuel메소드를 그대로 구현해 놓을 필요가 있을까?
어차피 다 자식 클래스에서 오버라이딩해서 사용하는데...

혹자는 이렇게 말할것이다..
"그냥 refuel메소드를 vehicle에서 지워버리면 안됨?"
그래도 물론 된다. 굳이 ElectricCar, Car 클래스가 refuel메소드를 오버라이딩하는 대신
직접 본인이 구현해서 사용하면 문제될것이 없다.

허나

Vehicle [] vec = {new Car(), new ElectricCar()};
vec[0].refuel();
vec[1].refuel();

이러한 접근이 불가능해진다.
우리는 그동안 다형성을 이용해
Vehicle 타입 참조변수에서 Car객체와 Electirc객체의 오버라이딩 된
refuel()메소드를 사용했는데 (이것을 동적바인딩이라고 부른다)

Vehicle 클래스에 refuel 메서드를 지워버리면
불가능해져버린다.

그럴때 필요한 것이 Abstract 클래스이다.

즉 자손 클래스에서 반드시 재정의 해서 사용하기 때문에
조상 클래스에서 구현한것이 사용될일 없는 메서드를
Abstract 메서드로 구현하면 되는것이고
그 Abstract 메서드가 클래스 내에 하나라도 존재한다면
그 클래스는 Abstract 클래스가 된다.

Abstract 메서드는 메서드의 선언부만 남기고 구현부는 세미콜론으로 대체한다.
그리고 메서드 선언부 부분에 abstract 키워드를 추가한다.
마찬가지로 Abstract 클래스에서도 선언부에 abstract 키워드를 추가해야한다.

Abstract 클래스의 특징

  • 당연히 구현부가 없는 abstract 메서드를 가지고 있으므로
    객체 생성이 불가능하다.
  • 하지만 조상 클래스 타입으로 자식 클래스 참조 가능하다. (다형성의 성질은 남아있음)
  • 만약 자식 클래스가 조상 abstract 클래스에서 상속받은 abstract 메서드를 오버라이딩하지
    않은 경우에 마찬가지로 자식 클래스도 abstract 클래스가 되며 객체 생성이 불가능하다.
  • 구현을 강제할 수 있다. (자식클래스가 abstract 조상 클래스의 abstract 메서드를 강제로 구현해야함, 안그러면 자식클래스에서 객체 생성시 에러 & 자식클래스에 abstract 키워드를 추가하지 않을시 에러남)

그럼 위에 예제를 abstract 클래스 기법을 적용해보면 아래와 같다.

abstract class Vehicle{
    private int posX, posY;
	
    public void move(int posX, int posY){
    	System.out.printf("%X, %Y로 이동%n", posX, posY);
    }
   
    public void stop() {
    	System.out.println("멈춰");
    }
 
    public abstract void refuel();
}

class Car extends Vehicle{
	public void refuel(){
    	System.out.println("가솔린을 넣습니다");
        } 
}

class ElectricCar extends Vehicle{
	public void refuel(){
    	System.out.println("전기를 충전합니다.");
        }
}
profile
현명한개발자가되자

0개의 댓글