추상Abstract 클래스
추상 클래스란 클래스가 완성되지 못한(미완성) 상태를 뜻한다. 클래스가 완성되지 못했다는 것은 클래스의 코드가 완전하지 못한 것이 아니라 미완성 메소드(추상 메소드)를 포함하고 있다는 뜻이다. 추상 클래스로는 인스턴스를 생성할 수 없고 상속을 통해 자손클래스를 구현하여 활용하게 된다.
추상 클래스는 바탕이 되는 조상클래스로서 새로운 클래스를 생성할 때 중요한 역할을 한다. 추상 클래스는 클래스 앞에 'abstract'를 붙이면 추상 클래스가 되고 'abstract'가 붙은 클래스는 추상 메서드를 포함하고 있으니 상속을 통해서 구현해야 한다는 것을 알 수 있다.
abstract class 클래스이름 {
..
}
추상 메소드
추상 메소드는 선언부만 정의(설계만)하고 구현부(실제 구현될 코드)는 정의하지 않은 메소드이다. 추상 메소드를 선언부만 정의하는 것은 메서드의 내용이 상속받는 클래스의 목적에 따라 달라지기 때문에 상속받는 클래스에서 구현하도록 하는 것이 목적이다.
추상 메소드는 메소드 앞에 'abstract'를 붙이면 추상 메소드가 된다. 추상 클래스를 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상 메소드를 전부 구현해 주어야 한다.
// 주석으로 추상 메소드가 어떤 기능을 구현해야 하는지 알려준다.
abstract 리턴타입 메소드이름();
abstract class Player {
//음악을 재생시키는 기능을 구현하여야 한다.
abstract void play(int pos); //추상메소드
//음악을 정지시키는 기능을 구현하여야 한다.
abstract void stop(); //추상메소드
}
class Mp3Player extends Player {
void play(int pos) { /* 기능 구현 */ }
void stop() { /* 기능 구현 */ } //추상클래스의 추상메서드를 모두 구현했음
}
//추상클래스의 추상메서드를 모두 구현하지 않았으면
//자손클래스 역시 추상클래스로 지정하여야 한다.
abstract class Speaker extends Player {
void play(int pos) { /* 기능 구현 */ }
}
추상 클래스 작성법
상속이 자식 클래스를 만드는데 조상 클래스를 사용하는 것이라면 추상화는 이와 반대로 기존의 클래스의 공통부분을 추출해서 조상 클래스를 만드는 것으로 생각하면 된다.
abstract class Player {
boolean pause; //일시정지 상태를 저장하는 변수
int playbackLocation; //재생 위치를 저장하는 변수
Player() { //추상클래스의 생성자 정의
pause = false;
playbackLocation = 0;
}
//지정된 위치에서 재생을 시작하는 기능을 구현하여야 한다.
abstract void play(int pos); //추상메소드
//재생을 멈추는 기능을 구현하여야 한다.
abstract void stop(); //추상메소드
void play() {
play(playbackLocation); //추상메소드를 사용할 수 있다.
}
void pause() {
if(pause) { //pause가 true(정지)일 때 pause가 호출되면
pause = false; //pause에 false를 저장하고
play(playbackLocation); //현재위치에서 재생
} else { //pause가 false(재생)일 때 pause가 호출되면
pause = true; //pause에 true를 저장하고
stop(); //재생 정지
}
}
}
class Mp3Player extends Player { //Player클래스를 조상으로 정의
void play(int playbackLocation) { /* 기능 구현 */ }
void stop() { /* 기능 구현 */ }
int currentTrack; //Mp3클래스에 새로 추가된 멤버변수
//새로운 기능 추가
void nextTrack() {
currentTrack++;
}
//새로운 기능 추가
void preTrack() {
if(currentTrack > 1) {
currentTrack--;
}
}
}
인터페이스Interface
인터페이스는 추상클래스의 일종으로 추상메소드를 포함하고 있지만 추상화가 심해서 일반 메소드, 멤버변수를 가질 수 없고 오직 추상 메소드와 상수만을 멤버로 가질 수 있다.
인터페이스 작성법
인터페이스를 작성하는 방법은 클래스를 작성하는 방법과 동일한데 'class' 키워드 대신 'interface' 키워드를 사용하면 된다.
interface 인터페이스이름 {
public static final 타입 상수이름 = 상수값;
public abstract 메서드이름(매개변수);
}
인터페이스의 상속
인터페이스는 인터페이스간에만 상속관계를 맺을 수 있고 클래스와는 달리 다중상속(여러 인터페이스로부터 상속)을 맺는 것이 가능하다.
interface Playable {
void play(); //재생기능
}
interface Pauseable {
void pause(); //일시정지기능
}
interface MusicPlayable extends Playable, Pauseable {
}
인터페이스 구현
인터페이스도 추상클래스와 마찬가지로 그 자체로는 인스턴스를 생성할 수 없고 추상클래스가 상속을 통해 추상메소드를 완성해 나가는 것과 같이 인터페이스도 마찬가지로 자신에게 정의된 추상메서드의 내용을 정의해 주는 클래스를 작성해 주어야 한다. 추상 클래스가 자신을 상속받는 클래스를 정의하는 것과 같이 인터페이스는 구현한다는 키워드 'implements'를 사용한다.
class 클래스이름 implements 인터페이스이름 {
//인터페이스에 정의된 추상메소드 구현
}
class Mp3Player implements MusicPlayable {
public void play() {
//인터페이스에 정의된 추상메소드 구현
}
public void pause() {
//인터페이스에 정의된 추상메소드 구현
}
}
인터페이스의 다형성
다형성이란 자손클래스의 인스턴스를 조상타입의 참조변수로 참조하는 것을 말하는데 인터페이스 역시 다형성을 구현한 클래스의 조상이므로 해당 인터페이스의 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며 인터페이스 타입으로 형변환 또한 가능하다.
MusicPlayable m = (MusicPlayable)new Mp3Player();
//또는 MusicPlayable m = new Mp3Player();
void pause(MusicPlayable m) {
//...
}
MusicPlayable method() {
//...
return new Mp3Player();
}