Do it! 자바 프로그래밍 입문 9장~10장
상속되기 위해 만드는 클래스.
추상클래스는 인스턴스화될 수 없다. (자식을 참조할 수는 있다.)
접근지시자 abstract class 클래스식별자 {
abstract 반환형 method_1(매개변수);
반환형 method_2(매개변수){
구현내용
}
}
method_1
위 코드에서 method_1은 추상메소드로, body가 없다.
이 클래스를 상속받는 자식클래스에서 오버라이드하여 구현한다.
즉, 이 클래스의 자식은 method_1를 구현할 책임(의무)이 있고, 이 클래스는 자식에게 구현을 위임했다. 고 표현할 수 있다.
method_2
method_2는 body가 있는 구현된 메소드이다.
final 키워드를 붙여 자식클래스에서 시나리오를 변경할 수 없도록 제한할 수 있음abstract class Animal {
protected int id;
protected int huntCnt;
public Animal(int id) {
this.id = id;
huntCnt = 0;
System.out.println("No. "+id+" born");
}
public abstract String move(); // abstract method
public abstract String attack(); // abstract method
public void bark(){} // hook method
final public void log(String action) {
System.out.println("[ID #"+id+"] "+action);
}
final public void hunt() { // Template method
log(move());
bark();
log(attack());
log(move());
huntCnt++;
}
public int getHuntCnt() {
return huntCnt;
}
}
class Gorani extends Animal {
public Gorani(int id) {
super(id);
}
@Override
public String move( ) {
return "run";
}
@Override
public String attack() {
return "bite";
}
@Override
public void bark() {
log("kwwawawkakw!!");
}
}
public class Test {
public static void main(String[] args) {
Gorani gorani = new Gorani(53);
gorani.hunt();
gorani.hunt();
System.out.println(gorani.getHuntCnt());
/*
No. 53 born
[ID #53] run
[ID #53] kwwawawkakw!!
[ID #53] bite
[ID #53] run
[ID #53] run
[ID #53] kwwawawkakw!!
[ID #53] bite
[ID #53] run
2
*/
}
}
public static final삽입public abstract삽입default 키워드static 키워드private 키워드private static 키워드interface POS {
int MAX = 53; // 상수
public static getDoubleOfMAX() { // 정적메소드
return MAX * 2;
}
private void supportSomthing(){ // private 메소드
// 구현 내용
}
int addItem(int itemId); // 추상메소드
int removeItem(int itemId); // 추상메소드
default int pay(){
// 기본 구현 내용
};
}
abstract class GeneralPOS implements POS {
@Override
public int addItem(int itemId){ ... }
}
class MyPOS implements POS {
@Override
public int addItem(int itemId){ ... }
@Override
public int removeItem(int itemId){ ... }
@Override
public int pay(){ ... } // 기본구현 메소드도 오버라이드 가능
}
인터페이스를 구현(implement)하면 둘 중 하나가 된다.
인터페이스를 구현한 추상메소드를 상속해 구상메소드를 만들 수도 있다.
어떤 인터페이스 타입으로 그 인터페이스를 구현한 클래스를 참조할 수 있다.
interface IA {
int CONST_A = 53;
void methodA ();
}
class Gorani implements IA {
@Override
public void methodA () {
System.out.println(CONST_A);
}
}
public class Test {
public static void main(String[] args) {
IA gorani = new Gorani();
gorani.methodA(); // 53
}
}
클래스 상속은 하나만 받을 수 있지만, 인터페이스는 여러 개를 동시에 구현할 수 있다. 콤마(,)로 인터페이스 식별자를 구분한다.
public interface IA { }
public interface IB { }
class Gorani implements IA, IB {
// 구현내용
}
interface IA {
int CONST_A = 53;
void methodA ();
}
interface IB {
int CONST_B = 535353;
int methodB (int n);
}
class Gorani implements IA, IB {
@Override
public void methodA () {
System.out.println(CONST_A);
}
@Override
public int methodB (int n) {
return n;
}
void printConstants() {
System.out.println(CONST_A + " " + CONST_B);
}
}
public class Test {
public static void main(String[] args) {
Gorani gorani = new Gorani();
gorani.methodA(); // 53
int tmp = gorani.methodB(111);
System.out.println(tmp); // 111
gorani.printConstants(); // 53 535353
}
}
interface IA {
void methodA();
}
interface IB extends IA {
default void methodA() { // 기본구현 메소드
System.out.println("Default A in IB");
}
void methodB();
}
interface IC extends IA, IB {
void methodC();
}
class Class_IB_1 implements IB {
// IB인터페이스는 methodA(), methodB() 두 개의 메소드를 포함
// ---> Class_B는 methodB()에 대해서만 구현의무 있음
// (methodA는 이미 IB에서 기본구현됨)
@Override
public void methodB() {
System.out.println('B');
}
}
class Class_IB_2 implements IB {
// IB인터페이스는 methodA(), methodB() 두 개의 메소드를 포함
// ---> Class_B는 methodB()에 대해서만 구현의무 있음
// (methodA는 이미 IB에서 기본구현됨)
@Override
public void methodA() { // IB의 기본구현 메소드 오버라이드
System.out.println('A');
}
@Override
public void methodB() {
System.out.println('B');
}
}
class Class_IC implements IC {
// IC인터페이스는 methodA(), methodB(), methodC() 세 개 메소드 포함
// --> Class_IC는 methodB(), methodC()에 대해 구현의무 있음
// (methodA는 이미 IB에서 기본구현됨)
@Override
public void methodB() {
System.out.println("B in Class_IC");
}
@Override
public void methodC() {
System.out.println("C in Class_IC");
}
}
public class Test {
public static void main(String[] args) {
IB ib1 = new Class_IB_1();
ib1.methodA(); // Default A in IB
ib1.methodB(); // B
IB ib2 = new Class_IB_2();
ib2.methodA(); // A
ib2.methodB(); // B
IC ic = new Class_IC();
ic.methodA(); // Default A in IB
ic.methodB(); // B in Class_IC
ic.methodC(); // C in Class_IC
}
}
interface I { ... }
class C { ... }
class MyClass extends C implements I {
// 구현
}