본문 바로가기

Backend/Java

[JAVA] 추상클래스(Abstract Class)

728x90

* 추상메서드
- 추상메소드란 선언은 되어 있으나 코드가 구현되어 있지 않은 껍데기만 있는 메소드이다. 

* 추상클래스 : 추상클래스는 추상 메서드가 하나라도 있으면 그 클래스는 추상클래스가 된다. 
(만드는 2가지 방법 )
1) 추상 메소드를 포함하는 클래스
2) 추상 메소드가 없지만 abstract(예약어)로 선언한 클래스

* 추상 클래스는 객체를 생성할 수 없다. 
응용프로그램은 추상 클래스의 객체(인스턴스)를 생성할 수 없다. 
추상클래스는 본래 객체를 생성할 목적으로 만드는 클래스가 아니다. 
추상 클래스에는 실행 코드가 없는 미완성 상태인 추상 메소드가 있을 수 있기 때문에,
추상 클래스의 객체를 생성하는 코드에는 컴파일 오류가 발생한다. 
컴파일 오류 , 추상 클래스의 객체를 생성할 수 없다. 
 
 그러나, 추상클래스의 레퍼런스 변수를 선언하는 것은 오류가 아니다.

 

* 추상 클래스의 상속
 추상 클래스를 단순히 상속받는 서브 클래스는 추상 클래스가 된다. 
 추상 클래스의 추상 메소드를 그대로 상속받기 때문이다. 
 그러므로 서브 클래스에 abstract를 붙여 추상 클래스임을 명시해야 컴파일 오류가 발생하지 않는다. 
 
 다음과 같이 추상 클래스 Shape을 상속 받는 Line 클래스에서 추상 메소드인 draw()를 오버라이딩하지 않으면 
 자동으로 추상 클래스가 되므로, Line은 abstract 키워드를 사용하여 추상 클래스임을 명시해야 한다. 

 abstract class Shape{
 	public Shape(){}
 	public void paint(){	
 		draw();
 	}
 	abstract public void draw(); //추상메소드
 }
 
 //draw()를 Override하지 않았기 때문에 추상 클래스 이다. 
 abstract class Line extends Shape{
 	public String toString(){
 		return "Line";
 	}
 }

 * 추상 클래스의 구현과 목적
 추상클래스의 구현이란, 슈퍼 클래스에 선언된 모든 추상 메소드를 서브 클래스에서 오버라이딩하여, 실행 가능한 코드로 구현하는 것을 말한다.
 
 - Line, Rect, Circle은 추상클래스 Shape를 상속받아 만든 서브 클래스 들로서 draw()를 오버라이딩 하여 구현한것이다.
 => 모두 추상클래스가 아니며 인스턴스를 생성할 수 있다. 
 

abstract class Shape{
 	public abstract void draw(); //추상메소드
 }
 
 class Line extends Shape{
 	@Override
 	public void draw(){
 		System.out.println("Line");
 	}	
 }
 class Rect extends Shape{
 	@Override
 	public void draw(){
 		System.out.println("Rect");
 	}	
 } 
 class Circle extends Shape{
 	@Override
 	public void draw(){
 		System.out.println("Circle");
 	}	
 }

=> 추상 클래스 Shape을 상속받아 구현한 Line, Rect, Circle 클래스들. 


그렇다면? 그냥 추상 클래스를 받지않고 기본 클래스를  오버라이딩 한것과,  추상 클래스를 상속받아 오버라이딩 한것중 어느 것이 바람직 할까?

 

 추상 클래스가 아닌 클래스를 오버라이딩한다면 draw() 대신에 오타를 내도 컴파일 오류가 없을 것이다.  하지만, 추상클래스로 구현한 Shape의 draw()메소드가 추상메소드 이기 때문에 이를 상속받는 Line, Rect, Circle 클래스에서는 반드시 draw()를 오버라이딩을 해야 한다. 오버라이딩하지 않거나 이름을 잘못 작성한다면 컴파일 오류가 발생한다.  추상 클래스는 추상 메소드를 통해 서브 클래스가 구현할 메소드를 명료하게 알려주는 "인터페이스"의 역할을 하고, 서브 클래스는 추상 메소드를 모적에 맞게 구현하는 "다형성"을 실현할 수 있다. 

 

즉 추상클래스로 하는것이 다형성을 실현할 수 있는 방법이라 할 수 있다.

 

추상클래스의 용도는 응용프로그램의 설계와 구현을 분리하는 것이다. 추상 클래스로 기본 방향을 잡안호고, 서브 클래스에서 구현하여 구현작업을 쉽게 하는 것이다. 또한 계층적 상속 관계에서 클래스를 구조를 만들기 위한 용도에 적합하다. 


추상클래스를 활용하여 결과를 출력하면 다음과 같다. 

abstract class Shape {
	public abstract void draw(); // 추상메소드
}

class Line extends Shape {
	@Override
	public void draw() {
		System.out.println("Line");
	}
}

class Rect extends Shape {
	@Override
	public void draw() {
		System.out.println("Rect");
	}
}

class Circle extends Shape {
	@Override
	public void draw() {
		System.out.println("Circle");
	}
}

public class UserDraw {

	public static void main(String[] args) {
		Shape[] ref = new Shape[3];
		//다형성을 이용한다. 
		ref[0] = new Line();
		ref[1] = new Rect();
		ref[2] = new Circle();
		for(int i =0; i<ref.length;i++){
			ref[i].draw();
		}
	}
}

실행결과

 

참고자료 :명품 Java 프로그래밍, 생능출판, 황기태 저, 2019

728x90