추상클래스와 추상메서드
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() { /* 선택된 대상을 내린다. */ }
}
'java' 카테고리의 다른 글
[java] 헷갈리는 return의 의미: 결과반환 or 호출한 곳으로 가기 (0) | 2023.02.22 |
---|---|
[java] 인터페이스 interface (0) | 2023.02.21 |
[JAVA/스프링] setAttribute getParameter / getParameter (0) | 2023.02.21 |
[JAVA] foreach문 (0) | 2023.02.20 |
[java] Generics(제네릭), Collection(컬렉션)-list, map (0) | 2023.02.20 |
댓글