본문 바로가기
객체 지향 프로그래밍/Java

chapter 9. 추상 클래스

by xangmin 2022. 3. 11.
반응형

9-1. 추상 클래스

추상 클래스란?

추상 클래스를 영어로 표현하면 abstract class이고, 추상 클래스가 아닌 클래스는 concrete class라고 한다. 현재까지 만든 클래스는 모두 concrete이다.

 

추상 클래스는 항상 추상 메서드를 포함한다. 추상 메서드는 구현 코드가 없다. 함수의 구현 코드가 없다는 것은 함수 몸체(body)가 없다는 뜻이다.

int add(int x, int y){
	return x + y;		// {} 안의 내용이 함수 몸체
}

 

중괄호 {}로 감싼 부분을 함수 구현부라고 한다. 이 부분이 없는 함수는 추상 함수이고 자바에서는 추상 메서드라고 한다. 추상 메서드는 다음과 같이 선언만 하며 abstract 예약어를 사용한다. 그리고 {} 대신 ;를 쓴다.

abstract int add(int x, int y);

정리하자면, 자바에서 추상 메서드는 abstact 예약어를 사용하여 선언만 하는 메서드이다.

 

추상 클래스 구현하기

구체적으로 구현하지 않은 추상 메서드를 어떻게 사용하는지 알아보자. 

package abstractex;

public class Computer{
	public void display();
    public void typing();
    public void turnOn(){
    	System.out.println("전원을 킵니다.");
    }
    public void turnOff(){
    	System.out.println("전원을 끕니다.");
    }
}

Computer 클래스 내부에 추상 메서드 display()와 typing()을 선언하고, 구현 메서드 turnOn()과 turnOff를 작성한다. 그러면 완전하게 구현되지 않은 두 추상 메서드에서 오류가 발생한다. display()나 typing()위에 마우스를 올리면 오류를 해결할 수 있는 방법으로 다음 두 가지를 제시한다.

 

1) Add body (몸체 부분을 작성하세요.)

2) Chage 'Computer.display' to 'abstract' (이 메서드를 추상 메서드로 바꾸세요.)

 

package abstractex;

public class Computer{
	public abstract void display();
    public abstract void typing();
    public abstract void turnOn(){
    	System.out.println("전원을 킵니다.");
    }
    public void turnOff(){
    	System.out.println("전원을 끕니다.");
    }
}

하지만 이번에는 메서드와 클래스 이름에 모두 오류가 표시된다. 왜나하면 추상 메서드가 속한 클래스를 추상 클래스로 선언하지 않았기 때문이다. 다시 오류 메세지 내용을 보면 다음과 같다.

 

1) Remove 'abstract' modifier (메서드에서 abstract 예약어를 제거하세요.)

2) Make type 'Computer' abstract (Computer 클래스를 추상 클래스로 만드세요.)

 

Computer를 추상 클래스로 선언하지 않았으므로 이 메서드에서 abstract 예약어를 빼거나 Computer 클래스를 추상 클래스로 만들어야 오류가 없어진다는 것이다. 두 번째 옵션을 클릭해서 Computer 클래스를 추상 클래스로 만들어보자.

package abstractex;

public abstract class Computer{
	public abstract void display();
    public abstract void typing();
    public abstract void turnOn(){
    	System.out.println("전원을 킵니다.");
    }
    public void turnOff(){
    	System.out.println("전원을 끕니다.");
    }
}

 

 

Computer 클래스를 다음과 같이 구현한 것은 'Computer를 상속받는 클래스 중 turnOn()과 turnOff() 구현 코드는 공통이다. 하지만 display()와 typing()은 하위 클래스에 따라 구현이 달라질 수 있다. 그래서 Computer에서 구현하지 않고, 이 두 메서드 구현에 대한 책임을 상속받는 클래스에 위임한다'라는 의미이다. 따라서 COmputer 클래스의 추상 메서드는 추상 클래스를 상속받는 DeskTop과 Notebook에서 실제로 구현하게 된다. 이 클래스의 상위 클래스에서는 하위 클래스도 공통으로 사용할 메서드를 구현하고, 하위 클래스마다 다르게 구현할 메서드는 추상 메서도르 선언해두는 것이다.

 

추상 클래스 상속 받기

그렇다면 Desktop 클래스를 만들어보자. 다음과 같이 DeskTop 클래스를 선언하고 Computer 클래스를 상속받는다.

package abstractex;

public class DeskTop extends Computer {
	//...
}

상속받은 DeskTop 클래스에 빨간색 줄로 오류 표시가 보인다. 마우스를 올려서 메시지를 확인해보면 다음과 같다.

 

1) Add unimplemented methods (구현되지 않은 메서드를 구현하세요.)

2) Make type 'DeskTop' abstract (DeskTop 클래스를 추상 클래스로 만드세요.)

 

원래 Computer는 추상클래스다. 추상 클래스를 상속받는 클래스는 추상 클래스가 가진 메서드를 상속받는다. 따라서 상속받는 클래스는 추상 메서드를 포함한다. 그렇기 때문에 추성 메서드를 모두 구현하던가 아니면 DeskTop도 추상 클래스로 만들던가 둘 중 하나를 해야한다. 즉 추상 클래스를 상속 받는 하위 클래스는 구현되지 않은 추상 메서드를 모두 구현해야 구체적인 클래스가 된다. 예를 들어 추상 메서드가 두 개인데 그 중 하나만 구현하면 이 역시 구현이 안된 추상 메서드를 포함하는 것이므로 추상 클래스입니다. Add unimplemented methods 옵션을 눌러보면 비어 있던 클래스 내부에 다음과 같은 코드가 생성된다.

@Override
public void display(){
	//..
}

@Override
public void typing(){
	//..
}

 

추상 메서드 구현하기

package abstractex;

public class DeskTop extends Computer {
	@Override
	public void display(){
		System.out.println("DeskTop display()");	//추상 메서드 몸체 코드 작성
	}

	@Override
	public void typing(){
		System.out.println("DeskTop typing()");		//추상 메서드 몸체 코드 작성
	}
}

 

마찬가지로 NoteBook 클래스도 구현한다.

package abstractex;

public abstract class NoteBook extends Computer {
	@Override
	public void display(){
		System.out.println("NoteBook display()");	//추상 메서드 몸체 코드 작성
	}
}

클래스에서 상속받은 추상 메서드를 모두 구현하지 않고 display() 하나만 구현했다. 그러므로 NoteBook 클래스는 추상 메서드를 하나 가지고 있기 때문에 추상 클래스가 된다. NoteBook을 상속받은 MyNoteBook 클래스는 다음과 같이 구현할 수 있다.

 

package abstractex;

public class MyNoteBook extends NoteBook {
	@Override
	public void typing(){
		System.out.println("MyNoteBook typing()");	//추상 메서드 몸체 코드 작성
	}
}

MyNoteBook은 모든 추상 메서드가 구현된 클래스이므로 abstract 예약어를 사용하지 않는다.

 

추상 클래스를 만드는 이유

추상 클래스를 바탕으로 프로그램을 실행할 수 있는 테스트 프로그램을 작성해보자.

package abstractex;

public class ComputerTest{
	public static void main(String[] args){
    	Computer c1 = new Computer();
        Computer c2 = new DeskTop();
        Computer c3 = new NoteBook();
        Computer c4 = new MyNoteBook();
    }
}

Computer 클래스형으로 인스턴스를 4개 생성했다. 그런데 코드를 보면 Computer와 NoteBook에서 오류가 난다. 오류메세지를 확인해보면 Computer 클래스와 NoteBook 클래스를 인스턴스로 생성할 수 없다고 한다

 

Cannot instantiate the typoe Computer (클래스를 인스턴스로 생성할 수 없음)

 

추상 클래스는 인스턴스로 생성할 수 없다.

 

 

작성중...

 

 

 

 

 

반응형

댓글