본문 바로가기
java

[java] 추상클래스,추상메서드

by CodeMango 2023. 2. 21.

추상클래스와 추상메서드

 

1) 추상클래스란?

- 미완성 설계도. 즉, 미완성 메서드를 갖고 있는 클래스를 말합니다.

- 일반 클래스와 똑같은데, 미완성 메서드를 갖고 있다는 점이 다릅니다.

- 다른 클래스 작성에 도움을 주기 위해 사용합니다.

- 설계도가 미완성이므로 인스턴스(객체) 생성이 불가합니다.

Player p = new Player(); //에러. 추상클래스의 인스턴스(객체) 생성 불가

 

2) 미완성 메서드란?

{} 몸통이 없는 메서드를 말합니다.

abstract class player{
	abstract void play();		// 몸통{} 이 없는 미완성 메서드
	abstract void stop(); 		// 몸통{} 이 없는 미완성 메서드
    
    // 몸통{} 이 없는 미완성 메서드는 추상메서드!

3) 구현

추상클래스에는 {}몸통이 없으므로, 상속(player :조상, AudioPlayer :자손)을 통해 추상 메서드에서 {}몸통을 만들어주면

메서드가 완성됩니다.

{}몸통을 만드는 것을 구현이라고 하고, 이렇게 추상 메서드가 완성되면 인스턴스 생성이 가능합니다.

즉, AudioPlayer의 객체를 만들 수 있습니다.

 

아래와 코드가 추가되면 위 코드의 추상클래스는 미완성 설계도지만 추상메서드를 통해 완성된 설계도가 됩니다.

class AudioPlayer extends Player {
	void play(int pos) {내용생략}	// 추상메서드 몸통{} 만들기 ->구현 
    void stop() {내용생략}		// 추상메서드 몸통{} 만들기 ->구현
    
AudioPlayer ap = new AudioPlayer(); 	// 객체 생성 가능

//Player가 조상이므로 아래와 같이 객체 생성할 수도 있다.
Player ap = new AudioPlayer();
//조상			자손			: 다형성

 

4) 추상메서드란?

미완성 메서드. 구현부(몸통{})이 없는 메서드

메서드는 선언부와 구현부로 나뉘는데, 선언부만 있고 구현부가 없는 메서드가 추상메서드입니다.

abstract 리턴타입 메서드이름();	//추상메서드

추상메서드는 꼭 필요하지만, 메서드 내용이 자손마다 다르게 구현될 것으로 예상될 경우에 쓰인다.

굳이 몸통을 구현할 필요가 없기 때문이다.

<코드해석>

Player라는 클래스는 추상메서드를 가지고 있으므로 추상클래스입니다.

 

이 추상클래스를 상속받아서 만든 AudioPlayer라는 클래스는 상속받은 2개의 메서드의 {}몸통을 만들어서 추상메서드를 구현했습니다. 조상으로부터 상속을 받앗을 때는 메서드를 반드시 다 구현해야 완전한 클래스가 됩니다.

따라서 이 추상클래스는 완전한 클래스가 되어 abstract를 붙이지 않습니다.

반면에, 세번째 코드는 추상메서드를 두개 중 하나만 구현하여 미완성입니다. 따라서 abstract를 붙였습니다.

 

5) 추상메서드 호출

추상클래스는 다른 일반 클래스와 같으나, 추상메서드를 포함한 점이 다르다.

추상클래스에도 iv가 있고, 생성자가 있어야 한다.  

 

* 메서드는 선언부만 알면 호출가능하므로 추상메서드도 호출 가능하다 * 

play() 메서드는 인스턴스메서드이고, 객체 생성 후에 호출할 수 있다.

나중에 상속을 통해 자손이 {}몸통을 완성하면, 객체를 생성할 수 있으므로,

play()라는 추상메서드를 호출할 수 있고, 호출 시에 {}몸통이 실행된다.

 

6) 추상클래스의 장점

-> 구체화된 코드보다 유연해서 변경에 유리합니다.

추상클래스의 대표적인 Calendar클래스는 객체생성할 때 원래대로라면

Calendar cal = new Calendar(); 라고 써야하지만, 

아래와 같이 유연하게 쓸 수 있습니다.

Calendar cal = Calendar.getinstance();

 

 

 

이제, 추상클래스를 활용한 예제를 보겠습니다.

 

예제1.

//추상클래스(추상메서드를 가진 클래스 가진 미완성클래스)
abstract class Player{ // 추상메서드를 추가하면 class에도 abstract 추가해야
					
	
	// void play(int pos); //몸통이 없으니까 에러난다.
	//따라서 이렇게 써준다
	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) {
//		Player p = new Player(); // 오류.추상클래스는 객체를 생성할 수 없다.
		AudioPlayer ap = new AudioPlayer();	// 추상클래스 상속 받아서 완성해주면 객체 생성할 수 있다.
//		Player ap = new AudioPlayer(); 	// 다형성 : 조상 = 자손으로도 객체 생성 가능
		ap.play(100);
		ap.stop();		
	}
	//콘솔값 : 100위치부터 play합니다
	//		  재생을 멈춥니다

}

 

 

더 자세한 내용은 자바의정석 추상클래스의 작성1 영상을 참조

공통부분 unit클래스 정의

https://www.youtube.com/watch?v=SBdXXWIB3To&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=87 

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("Tank[x=" + x + ",y=" + y + "]");
	}
	void changeMode() { /* 공격모드를 변환한다. */ }
}

class Dropship extends Unit { // 수송선
	void move(int x, int y) {
		System.out.println("Dropship[x=" + x + ",y=" + y + "]");
	}
	void load()   { /* 선택된 대상을 태운다. */ }
	void unload() { /* 선택된 대상을 내린다. */ }
}

댓글