
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 인스턴스 생성 가능(위에서 추상메서드를 구현해줬기 때문)
/* 주석을 통해 어떤 기능을 수행할 목적으로 작성하였는지 설명한다. */
abstract 리턴타입 메서드이름();
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{
void play(int pos){/* 내용 생략 */} //추상메서드를 구현
// 두개 다 구현하면 완성된 메서드이지만 하나만 구현했기 때문에 미완성이므로 제어자 abstract붙여줘야 함
}
// 일부만 구현해도 되지만 그렇게 되면 여전히 미완성인 상태이므로 abstract 클래스인 것
class Marine {//보병
int x, y;// 현재 위치
void move(int x, int y){/* 지정된 위치로 이동 */}
void stop(){/* 현재 위치에 정지 */}
void stimPack(){/* 스팀팩을 사용한다. */}
}
class Tank { //탱크
int x, y;// 현재 위치
void move(int x, int y) { /* 지정한 위치로 이동 */}
void stop() { /* 현재 위치에 정지 */}
void changeMode(){/* 공격모드로 변경한다 */}
}
class DropShip { // 수송선
int x,y; // 현재 위치
void move(int x, int y){ /* 지정한 위치로 이동 */}
void stop(){ /* 현재 위치에 정지 */}
void load(){ /* 선택된 대상을 태운다. */}
void unload(){/* 선택된 대상을 내린다 */}
}
이렇게 세개의 클래스에서 공통된 부분을 모아 추상 클래스를 만들어준다.
여기서 move()메서드는 지상과 공중이라는 차이 떄문에 구현부가 다를 것이다. 그래서 구현부는 불일치 하기 때문에 선언부만 abstract로 선언해서 뽑아낸다.
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) { }
void stimPack() {}
}
class Tank extends Unit {
void move(int x, int y){}
void changeMode(){}
}
class DropShip extends Unit {
void move(int x, int y){}
void load(){}
void unload(){}
}
이렇게 함으로써 코드의 중복을 줄일 수 있다.
Unit[] group = new Unit[3];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new DropShip();
for(int i = 0 ; i < group.length;i++){
group[i].move(100,200);
}
다형성 특징 때문에 이렇게 각자의 객체를 배열에 담을 수 있다.
Unit 배열 group[i]에는 move메서드 호출이 가능하다.
이때 호출은 추상메서드를 호출하는 것이 아닌 구현된 메서드 move()가 호출되는 것이다.
Object[] group = new Object[3];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new DropShip();
for(int i = 0 ; i < group.length;i++){
group[i].move(100,200);
}
/* 에러!!!!! Object 클래스에 move메서드가 정의되어 있지 않다. */
추상클래스 작성의 장점
1. 코드 중복 제거
2. 추상클래스를 상속받는 자식클래스의 설계도 쉽게 작성(중복된 부분이 추상클래스로 묶여있으므로)
3. 코드 관리(수정)가 용이
4. 단계별로 추상클래스를 만들어놓으면 상속받으면서 점점 구체적으로 완성되가는 모습을 볼 수 있음
추상메서드의 집합
구현된 것이 전혀 없는 설계도. (껍데기, 모든 멤버가 public)
추상클래스와 인터페이스의 차이
interface 인터페이스이름 {
public static final 타입 상수이름 =값;
public abstract 메서드이름(매개변수목록);
}
/* public static final, public abstract 는 생략 가능 무조건 붙어야 하는 부분이기 때문에 생략해도 구현되어있다고 봄 */
class 클래스이름 implements 인터페이스이름{
//인터페이스에 정의된 추상메서드를 모두 구현해야 한다.
}
class Fighter implements Fightable {
public void move(int x, int y){}
public void attack(Unit u) {}
}
//추상클래스의 구현을 완성시키는 것과 같고 상속을 implements로 받는다는 것이 다름
class Fighter extends Unit implements Fightable {
public void move(int x, int y){}
public void attack(Fightable f) {}
}// 다중 상속의 문제는 충돌의 문제인데 구현부가 없는 추상메서드 집합인 인터페이스는 여기서 문제가 없기 때문에 가능하다.
Unit u = new Fighter();
Fightable f = new Fighter();
f.move(100,200);
f.attack(new Fighter());
interface Fightable {
void move(int x, int y);
void attack(Fightable f);
}// 자손객체 호출하는 건 가능한 대신 존재하는 두개만 호출 가능하고 사용가능하다.
- 인터페이스
- 두 대상(객체)간의 연결, 대화, 소통을 돕는 중간 역할을 한다.
/* 직접적인 관계의 두 클래스 (A-B : 강한 결합) */
class A {
public void methodA(B b){
b.methodB();
}
}
class B {
public void methodB() {
System.out.println("methodB()");
}
}
class InterfaceTest {
public static void main(String args[]){
A a = new A();
a.methodA(new B());
}
}
/* 사이에 인터페이스가 존재하는 두 클래스 (A-B : 느슨한 결합) */
class A {
public void methodA(I i){
i.methodB();
}
}
// 사이에 인터페이스가 존재하면 인터페이스를 통해 methodB를 호출하기 때문에 B와 직접적인 관계가 없어짐
Interface I { void.methodB(); } //선언
class B implements I {
public void methodB() { //구현
System.out.println("methodB()");
}
}
// B의 method()를 추상 메서드로 갖는 인터페이스 작성(선언과 구현을 분리)
class InterfaceTest {
public static void main(String args[]){
A a = new A();
a.methodA(new B());
}
}
✔ 오늘 한 일
1. Java 객체지향개념 강의 듣기(추상화, 인터페이스)
2. SQL 5주차 강의 듣기
3. 프로그래머스 문제 풀기
👀
객체지향 개념 강의를 다 들었다. 본격적으로 Java 교육 들어가기 전에 객체지향 개념은 공부하고 싶었는데 계획대로 할 수 있어서 뿌듯하다. 강의를 듣고 이해한 부분도 있지만 아직 부족함이 많다고 느꼈다. 들었던 강의를 조금씩이라도 반복해서 들어야겠다.