추상클래스(Abstract class)
1. 추상클래스란?
- 클래스가 설계도라면 추상클래스는 '미완성 설계도'
- 추상 메서드(미완성 메서드)를 포함하고 있는 클래스
- 추상메서드란? 선언부만 있고 구현부(몸통, body)가 없는 메서드
- 일반 메서드가 추상 메서드를 호출할 수 있다.(호출할 때 필요한 건 선언부)
- 완성된 설계도가 아니므로 인스턴스를 생성할 수 없다.
- 다른 클래스를 작성하는 데 도움을 줄 목적으로 작성된다.
추상메서드란 무엇인지 아래 코드를 통해 살펴보자
package javajungsuk;
abstract class Player{
abstract void play(int pos); //추상 메서드 몸통이 없는 미완성 메서드
abstract void stop(); //추상 메서드
//Player p = new Player(); 추상 클래스의 인스턴스 생성 불가
}
//추상클래스를 상속해서 추상 메서드를 완성해야 인스턴스 생성이 가능
class AudioPlayer extends Player{
void play(int pos) {/*내용 생략*/} //추상메서드를 구현한 부분 -> 몸통 만들어주는 것
void stop() {/*내용 생략*/} //추상메서드를 구현 -> 몸통 만들어주는 것
AudioPlayer ap = new AudioPlayer(); // OK
}
이때 Player는 추상클래스지만 AudioPlayer은 완성된 설계도로 추상클래스가 아님.
추상 메서드 호출 가능한 경우를 아래 코드를 통해서 살펴보도록 하자
package javajungsuk;
abstract class Player{
//iv(인스턴스변수)
boolean pause; //변수들
int currentPos;
//생성자
Player(){ //추상클래스도 생성자가 있어야 한다.
pause = false;
currentPos = 0;
}
//추상 메서드
abstract void play(int pos);
abstract void stop(); //몸통이({}) 없어야 한다.
//인스턴스 메서드
void play() {
play(currentPos); //추상메서드를 사용할 수 있다.(호출 선언부만 알면 호출가능)
//나중에 상속을 통해서 자손이 구현하면 호출 가능
}
}
아래의 실습코드를 통해서 추상클래스를 알아보자.
package javajungsuk;
abstract class Player{
abstract void play(int pos);
abstract void stop();
}
//추상클래스는 상속을 통해 완성해야 객체생성이 가능하기 때문에 상속을 통해서 구현을 먼저 해준다
class AudioPlayer extends Player{
void play(int pos) {
System.out.println(pos+"위치부터 play합니다.");
}
void stop() {System.out.println("재생을 멈춥니다.");}
}
public class PlayerTest {
public static void main(String[] args) {
//AudioPlayer ap = new AudioPlayer();
Player ap = new AudioPlayer(); //다형성 실제 가리키고 있는 것은 AudioPlayer
//실제 호출되는 건 AudioPlayer의 메소드이다.
ap.play(100);
ap.stop();
}
}
객체 생성이 불가한 경우 Feat. 조상의 추상 메서드를 자손이 모두 구현하지 않았을 경우
package javajungsuk;
abstract class Player{
abstract void play(int pos);
abstract void stop();
}
//추상클래스는 상속을 통해 완성해야 객체생성이 가능하기 때문에 상속을 통해서 구현을 먼저 해준다
abstract class AudioPlayer extends Player{
void play(int pos) {
System.out.println(pos+"위치부터 play합니다.");
}
public class PlayerTest2 {
public static void main(String[] args) {
/*위의 구현부가 완전하게 구현하지 않아서 - > 조상 클래스 안에 있는 메소드를 모두 구현하지 않음
아래 객체 생성이 불가함 이렇게 사용하면 에러가 난다. */
Player ap = new AudioPlayer(); //다형성 실제 가리키고 있는 것은 AudioPlayer
ap.play(100);
ap.stop();
}
}
2. 추상메서드란?
- 선언부만 있고 구현부(몸통, body)가 없는 메서드
- 꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우에 사용한다.
- 추상클래스를 상속받는 자손클래스에서 추상메서드의 구현부를 완성해야 한다.
추상메서드를 2개 물려받았는데 1개만 구현할 경우 abstract를 붙여서 사용해야 한다.
왜냐하면 조상에서 상속받은 메소드를 모두 구현하지 않아 미완성 상태이기 때문이다.
package javajungsuk;
abstract class Player{
//꼭 필요하지만 자손마다 다르게 구현될 경우 추상 메서드를 만들어 준다.
abstract void play(int pos); //추상 메서드 몸통이 없는 미완성 메서드
abstract void stop(); //추상 메서드
}
class AudioPlayer extends Player{
void play(int pos) {/*내용 생략*/} //추상메서드를 구현한 부분
void stop() {/*내용 생략*/} //추상메서드를 구현
}
abstract class AbstractPlayer extends Player{
//상속을 받아서 1개만 구현한 경우여서 abstract를 붙여주어야 한다.
void play(int pos) {/*내용 생략*/} //추상메서드 구현
}
3. 추상클래스의 작성
- 여러 클래스에 공통적으로 사용될 수 있는 추상클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만든다.
package javaStandard;
public class Ex7_10 {
public static void main(String[] args) {
Unit[] group = { new Marine(), new Tank(), new Dropship() };
for (int i = 0; i<group.length; i++)
group[i].move(100,200);
}
}
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 +"]");
}
void stimPack() {}
}
class Tank extends Unit{ //탱크
void move(int x, int y) {
System.out.println("Marine[x="+ x +",y= "+ y +"]");
}
void changeMode() {}
}
class Dropship extends Unit{ //
void move(int x, int y) {
System.out.println("Marine[x="+ x +",y= "+ y +"]");
}
void stimPack() {}
}
package javaStandard;
public class EX7_10_2 {
public static void main(String[] args) {
//Unit 타입의 참조변수 group
Unit2[] group = new Unit2[3];
group[0] = new Marine2();
group[1] = new Tank2();
group[2] = new Dropship2();
group[0].move(100,200);
group[1].move(100,200);
group[2].move(100,200);
}
}
abstract class Unit2{
int x,y;
abstract void move(int x, int y);
void stop() {/*현재 위치에 정지*/}
}
class Marine2 extends Unit2{ //보병
void move(int x, int y) {
System.out.println("Marine[x="+ x +",y= "+ y +"]");
}
void stimPack() {}
}
class Tank2 extends Unit2{ //탱크
void move(int x, int y) {
System.out.println("Tank[x="+ x +",y= "+ y +"]");
}
void changeMode() {}
}
class Dropship2 extends Unit2{ //
void move(int x, int y) {
System.out.println("Dropship[x="+ x +",y= "+ y +"]");
}
void stimPack() {}
}
// 위의 코드와 아래 코드는 같다. 간결하게 바꾸는 것의 차이.
4. 추상화가 필요한 이유
5. 추상화 VS 구체화
추상화된 코드는 구체화된 코드보다 유연하다. ~> 변경에 유리하다
GregotianCalendar cal = new GregotianCalendar();//구체적
Calendar cal = Calendar.getInstance(); //추상적(추상클래스)
'Java > 객체지향' 카테고리의 다른 글
객체지향 개념 끝 (0) | 2021.12.14 |
---|---|
[객체지향][자바의 정석] - 7.7 인터페이스(Interface) (0) | 2021.12.03 |
[객체지향][자바의 정석] - 7.5 다형성 (0) | 2021.11.15 |
[객체지향][자바의 정석] - 7.4 제어자 (0) | 2021.11.11 |
[객체지향][자바의 정석] - 7.2 오버라이딩(Overriding) (0) | 2021.11.08 |