# 상속 : 부모(상위) 클래스의 모든 속성, 메소드를 자식(하위) 클래스가 물려받는 것
- 동일표현
상위클래스(super class), 부모클래스(parents class), 기초클래스(base class)
하위클래스(sub class), 자식클래스, 유도클래스(derived class)
ex)
class AAA //상위 클래스
{
public int num1;
public void printAAA()
{
System.out.println("AAA");
}
}
class BBB extends AAA // 하위 클래스
{
public int num2;
public void printBBB()
{
System.out.println("BBB");
}
}
class ABMain
{
public static void main(String[] args)
{
BBB bbb = new BBB();
bbb.num2 = 10;
bbb.printBBB();
bbb.num1 = 20; //AAA 클래스를 상속 받았기 때문에 num1에 접근 가능
bbb.printAAA(); // 결과 : AAA
}
}
- 상속을 받은 경우 상위 클래스가 하위 클래스의 객체 주소를 참조할 수 있다.
하지만 하위 클래스가 역으로 참조는 불가능하다.
ex)
ex)
class AAA
{
}
class BBB extends AAA
{
}
class ABMain
{
public static void main(String[] args)
{
AAA aaa = new BBB(); // 참조 가능
BBB bbb = new AAA(); // 결과 : error 발생
}
}
★ 컴파일러가 가리키는 곳의 객체를 AAA 클래스의 객체라고 생각하기 때문에 에러 발생
ex)
class AAA
{
public int num1;
public void printAAA()
{
System.out.println("AAA");
}
}
class BBB extends AAA
{
public int num2;
public void printBBB()
{
System.out.println("BBB");
}
}
class ABMain
{
public static void main(String[] args)
{
AAA aaa = new BBB();
aaa.printBBB();
// ★ 컴파일러가 가리키는 곳의 객체를 AAA 클래스의 객체라고 생각하기 때문에 에러 발생
(그림 참조할 것)
((BBB)aaa).printBBB();
// 이렇게 변경하면 객체를 참조할 수 있게 된다.
}
}
- 간접적인 상속 클래스도 객체 주소값 참조가 가능하다.
ex)
ex)
class AAA
{
public int num1;
public void printAAA()
{
System.out.println("AAA");
}
}
class BBB extends AAA
{
public int num2;
public void printBBB()
{
System.out.println("BBB");
}
}
class CCC extends BBB
{
public int num3;
public void printCCC()
{
System.out.println("CCC");
}
}
class ABMain
{
public static void main(String[] args)
{
BBB b1 = new BBB();
b1.num1 = 10;
b1.printAAA(); //상속하여 가능
CCC c1 = new CCC();
c1.num2 = 20; //상속하여 가능
c1.printBBB();
c1.num1=30;
c1.printAAA();
// AAA클래스의 모든 것을 BBB클래스에 상속했고, BBB클래스를 CCC클래스가 모두 상속 받았기 때문에 가능함
}
}
AAA a1 = new BBB(); // 상위 클래스가 하위 클래스 객체 주소 참조 가능
BBB b1 = new CCC(); // 마찬가지로 가능함
AAA a2 = new CCC(); // 간접적으로 CCC가 AAA에 상속받았기 때문에 객체 주소값 참조가능함
★ 메소드 오버라이딩
상위 클래스 있는 메소드를 하위 클래스가 재정의 하는 것
메소드 이름, 반환형, 매개변수까지 완벽하게 똑같아야만 한다.
메소드 오버라이딩을 하게 되면 최종적으로 메소드 오버라이딩된 메소드를 호출하게 된다.
ex)
class AAA
{
public int num1;
public void printHi()
{
System.out.println("AAA");
}
}
class BBB extends AAA
{
public int num2;
public void printHi()
{
System.out.println("BBB");
}
}
class CCC extends BBB
{
public int num3;
public void printHi()
{
System.out.println("CCC");
}
}
class ABMain
{
public static void main(String[] args)
{
AAA a1 = new AAA();
a1. printHi(); // 결과 : AAA
AAA a2 = new BBB();
a2. printHi(); // 결과 : BBB
AAA a3 = new CCC();
a3. printHi(); // 결과 : CCC
BBB b1 = new BBB();
b1. printHi(); // 결과 : BBB
BBB b2 = new CCC();
b2. printHi(); // 결과 : CCC
- 상속 관계에서도 메소드 오버로딩이 지원된다.
ㄴ 메소드 이름은 같으나 매개변수의 개수, 형이 다른 경우!
ex)
class AAA
{
public int num1;
public void printHi()
{
System.out.println("AAA");
}
public void printBye()
{
System.out.println("void");
}
}
class BBB extends AAA
{
public int num2;
public void printHi()
{
System.out.println("BBB");
}
public void printBye(int n)
{
System.out.println("int");
}
}
class CCC extends BBB
{
public int num3;
public void printHi()
{
System.out.println("CCC");
}
public void printBye(double n)
{
System.out.println("double");
}
}
class ABMain
{
public static void main(String[] args)
{
CCC c1 = new CCC();
c1. printBye(); // 결과 : void
CCC c1 = new CCC();
c1. printBye(5); // 결과 : int
CCC c1 = new CCC();
c1. printBye(3.14); // 결과 : double
- 메소드 오버라이딩의 접근제어지시자는 넓혀지는 방향은 가능하나 좁히는 방향을 줄 수 없다.
ex)
class AAA //BBB로 접근제어지시자 메소드 오버라이딩 하는 경우
{
private int num1; // 상속받은 메소드에서 private, default, protected, public 가능
int num1; // 상속받은 메소드에서 default, protected, public 가능
protected num1; // 상속받은 메소드에서 protected, public 가능
public num1; // 상속받은 메소드에서 public만 가능
}
- 하위 클래스의 생성자에서는 반드시 가장 먼저 상위 클래스의 생성자를 호출해야 한다.
ex)
class Man
{
public String name;
Man(String name)
{
this.name = name;
}
}
class BMan extends Man
{
public String company;
BMan(String name, String company)
{
super(name); //상위 클래스의 생성자를 의미,
// 하위 클래스의 생성자에서는 가장 먼저 호출하거나, 호출하는 형태가 되어야 한다(안하면 에러)
this.company = company;
}
public void printCS()
{
System.out.println(super.name+" "+this.company);
// super와 this 생략 가능
}
}
class MBMain
{
public static void main(String[] args)
{
BMan b = new BMan("홍길동“, ”삼성“);
}
}
- 접근제어지시자가 private인 경우 아무리 상속 받았어도 바로 접근 불가하다.
get 메소드를 사용해 간접적으로 접근시켜야 한다.
ex)
class Man
{
private String name;
Man(String name)
{
this.name = name;
}
public String getName() // 이 메소드를 상속 받기 때문에 이 메소드로 호출하면 된다.
{
return name;
}
}
class BMan extends Man
{
public String company;
BMan(String name, String company)
{
super(name); //상위 클래스의 생성자를 의미,
// ★하위 클래스의 생성자에서는 가장 먼저 호출하거나, 호출하는 형태가 되어야 한다(안하면 에러)
this.company = company;
}
public void printCS()
{
System.out.println(super.name+" "+this.company);
// super와 this 생략 가능 , private이므로 super.name으로 바로 호출 불가함
System.out.println(getName()+" "+this.company);
// 이렇게 상속받은 getName 메소드로 호출해야 에러 발생하지 않는다.
}
}
class MBMain
{
public static void main(String[] args)
{
BMan b = new BMan("홍길동“, ”삼성“);
}
}
- 생성자를 안만든 경우 자바 컴파일러가 디폴트 생성자를 삽입한다.
(자바 컴파일러는 생성자는 삽입하지 않으면 자동으로 이러한 형태로 생성자 자동으로 삽입시킴)
ex)
class AAA
{
AAA(){} // 자동으로 만들어진 생성자
}
class BBB extends AAA
{
BBB() /*
{ 자동으로 삽입된 생성자
super();
} */
}
- 상위 클래스에 만든 생성자가 있는 경우 하위 클래스에서 자동 생성자가 있는 경우 에러 발생한다.
ex)
class AAA
{
int num;
AAA(int num)
{
this.num=num;
}
}
class BBB extends AAA - 에러 발생
{
BBB() /*
{ 자동으로 삽입된 생성자
super();
} */
}
ex) 메소드 오버로딩으로 만든 예시
class AAA
{
int num;
AAA(int num)
{
this.num=num;
}
AAA(){} // 자동으로 삽입된 생성자
}
class BBB extends AAA
{
BBB() /*
{ 자동으로 삽입된 생성자
super();
} */
}
ex)
class AAA
{
int num;
AAA(int num)
{
this.num=num;
}
AAA(){} // 자동으로 삽입된 생성자
}
class BBB extends AAA
{
BBB()
{
super(); // 자동으로 삽입된 생성자
}
}
class BBB extends AAA
{
BBB()
{
super(); // 자동으로 삽입된 생성자
}
}
//Tip : 반드시 앞이 상위클래스여야 한다.
상위클래스 변수명 = new 하위클래스
- 하위 클래스에서 this.name=name으로 정의 가능하지만 점점 상속받을수록 할 일이 많아지기 때문에
정의는 본인 클래스에서 해줘야 깔끔하다.
ex)
class Man
{
String name;
public Man(String name)
{
this.name=name;
}
public void tellYourName()
{
System.out.println("My name is "+name);
}
}
class BusinessMan extends Man
{
String company; // 회사이름
String position; // 직급
public BusinessMan(String name, String company, String position)
{
super(name); //상위 클래스의 생성자를 가장 먼저 호출한 것
this.company=company;
this.position=position;
}
public void tellYourInfo()
{
System.out.println("My company is "+company);
System.out.println("My position is "+position);
tellYourName(); // Man 클래스를 상속했기 때문에 호출 가능!
}
}
class BasicInheritance
{
public static void main(String[] args)
{
BusinessMan man1
=new BusinessMan("Mr. Hong", "Hybrid 3D ELD", "Staff Eng.");
BusinessMan man2
=new BusinessMan("Mr. Lee", "Hybrid 3D ELD", "Assist Eng.");
System.out.println("First man info..........");
man1.tellYourName(); // My name is Mr. Hong
man1.tellYourInfo(); /* My company is Hybrid 3D ELD
My position is Staff Eng */
System.out.println("Second man info..........");
man2.tellYourInfo(); /* My company is Hybrid 3D ELD
My position is Assist Eng.
My name is Mr. Lee */
}
}
ex)
class Accumulator
{
private int val;
Accumulator(int init)
{
val=init;
}
protected void accumulate(int num)
{
if(num<0) // 음수는 누적 대상에서 제외!
return;
val+=num;
}
protected int getAccVal()
{
return val;
} //getVal이 올바른 표현(책의 예시일 뿐이다)
}
class SavingAccount extends Accumulator
{
public SavingAccount(int initDep)
{
super(initDep); // 통장개설 시 첫 입금액
}
public void saveMoney(int money)
{
accumulate(money);
}
public void showSavedMoney()
{
System.out.print("지금까지의 누적금액: ");
System.out.println(getAccVal()); // private이기 때문에 엑세스메소드를 사용한 것
}
}
class PrivateInheritance
{
public static void main(String[] args)
{
SavingAccount sa=new SavingAccount(1000);
sa.saveMoney(1000);
sa.saveMoney(1000);
sa.showSavedMoney(); // 결과 : 3000
}
}
ex)
class AAA
{
public static int num = 5;
}
class BBB extends AAA
{
}
class ABMain
{
public static void main(String[] args)
{
System.out.println(AAA.num);
System.out.println(BBB.num); // 결과 : 5
}
}
- 스테틱 메소드나 멤버변수도 상속 가능하다.
ex)
class Adder
{
public static int val=0;
public void add(int num)
{
val+=num;
}
}
class AdderFriend extends Adder
{
public void friendAdd(int num)
{
val+=num; //public이라 바로 접근 가능
}
public void showVal()
{
System.out.println(val);
}
}
class StaticInheritance
{
public static void main(String[] args)
{
Adder ad=new Adder();
AdderFriend af=new AdderFriend();
ad.add(1);
af.friendAdd(3);
AdderFriend.val+=5; //하위 클래스의 이름으로 접근, public이라 가능한 것
af.showVal();
}
}
- 상속이라고 한글로 번역 했으나 확장이라는 개념이 더 맞긴 하다.
상위 클래스의 요소를 갖고 하위 클래스가 더욱 확장되는 것이기 때문이다.
Q. 다음 클래스에 적절한 생성자를 삽입해보자.
그리고 이의 확인을 위한 main 메소드도 적절히 정의해 보자.
class Car // 기본 연료 자동차
{
int gasolineGauge;
}
class HybridCar extends Car // 하이브리드 자동차
{
int electricGauge;
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
int waterGauge;
public void showCurrentGauge()
{
System.out.println("잔여 가솔린 : " + gasolineGauge);
System.out.println("잔여 전기량 : " + electricGauge);
System.out.println("잔여 워터량 : " + waterGauge);
}
}
A.
class Car // 기본 연료 자동차
{
int gasolineGauge;
Car(int gasolineGauge)
{
this.gasolineGauge = gasolineGauge;
}
}
class HybridCar extends Car // 하이브리드 자동차
{
int electricGauge;
HybridCar(int gasolineGauge, int electricGauge)
{
super(gasolineGauge);
this.electricGauge = electricGauge;
}
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
int waterGauge;
HybridWaterCar(int gasolineGauge, int electricGauge, int waterGauge)
{
super(gasolineGauge, electricGauge);
this.waterGauge = waterGauge;
}
public void showCurrentGauge()
{
System.out.println("잔여 가솔린 : " + gasolineGauge);
System.out.println("잔여 전기량 : " + electricGauge);
System.out.println("잔여 워터량 : " + waterGauge);
}
}
class CarMain
{
public static void main(String[] args)
{
HybridWaterCar hwCar = new HybridWaterCar(10, 20, 30);
hwCar.showCurrentGauge();
}
}
A. private로 멤버변수를 변경한 경우, 출력값은 동일해야 한다. (get 메소드 사용 예시)
class Car // 기본 연료 자동차
{
private int gasolineGauge;
Car(int gasolineGauge)
{
this.gasolineGauge = gasolineGauge;
}
public int getGasolineGauge()
{
return gasolineGauge;
}
}
class HybridCar extends Car // 하이브리드 자동차
{
private int electricGauge;
HybridCar(int gasolineGauge, int electricGauge)
{
super(gasolineGauge);
this.electricGauge = electricGauge;
}
public int getElectricGauge()
{
return electricGauge;
}
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
private int waterGauge;
HybridWaterCar(int gasolineGauge, int electricGauge, int waterGauge)
{
super(gasolineGauge, electricGauge);
this.waterGauge = waterGauge;
}
public void showCurrentGauge()
{
System.out.println("잔여 가솔린 : " + getGasolineGauge());
System.out.println("잔여 전기량 : " + getElectricGauge());
System.out.println("잔여 워터량 : " + waterGauge);
}
}
class CarMain
{
public static void main(String[] args)
{
HybridWaterCar hwCar = new HybridWaterCar(10, 20, 30);
hwCar.showCurrentGauge();
}
}
A. private로 멤버변수를 변경한 경우, 출력값은 동일해야 한다. (메소드 오버라이딩 사용 예시)
메소드 오버라이딩 방법을 사용했을 때 훨씬 더 편리하게 변경이 가능하다.
class Car // 기본 연료 자동차
{
private int gasolineGauge;
Car(int gasolineGauge)
{
this.gasolineGauge = gasolineGauge;
}
public void showCurrentGauge()
{
System.out.println("잔여 가솔린 : " + gasolineGauge);
}
}
class HybridCar extends Car // 하이브리드 자동차
{
private int electricGauge;
HybridCar(int gasolineGauge, int electricGauge)
{
super(gasolineGauge);
this.electricGauge = electricGauge;
}
public void showCurrentGauge()
{
super.showCurrentGauge();
System.out.println("잔여 전기량 : " + electricGauge);
}
}
class HybridWaterCar extends HybridCar // 하이브리드 워터카
{
private int waterGauge;
HybridWaterCar(int gasolineGauge, int electricGauge, int waterGauge)
{
super(gasolineGauge, electricGauge);
this.waterGauge = waterGauge;
}
public void showCurrentGauge()
{
super.showCurrentGauge();
System.out.println("잔여 워터량 : " + waterGauge);
}
}
class CarMain
{
public static void main(String[] args)
{
HybridWaterCar hwCar = new HybridWaterCar(10, 20, 30);
hwCar.showCurrentGauge();
}
}
- 자바에서는 생성자가 상속되지 않는다.
ex)
HybridWaterCar hwCar = new HybridWaterCar(10); // 결과 : error
# 상속 ≠ 재활용
- 상속을 통해 상속한 클래스와 상속받은 클래스 간의 공통적인 규칙을 생성하기 위해 사용하는 것이다.
ex) 새 - 참새 - 짹짹
오리 - 꽥꽥
상속은 처음 설계부터 설정하는 것이지 재활용하는 것이 아니다.
재활용은 대개 패키지 단위로 이루어진다. ex) 병원 영수증 패키지
재활용은 클래스 단위로 이루어지지 않는다.
★is a 관계가 성립하면 상속 관계로 묶을 수 있다.
ex) notebook is a computer - computer(상위클래스), notebook(하위클래스)
ex)
class Computer
{
String owner;
public Computer(String name){owner=name;}
public void calculate()
{
System.out.println("요청 내용을 계산합니다.");
}
}
class NotebookComp extends Computer
{
int battary;
public NotebookComp(String name, int initChag)
{
super(name);
battary=initChag;
}
public void charging()
{
battary+=5;
}
public void movingCal()
{
if(battary<1)
{
System.out.println("충전이 필요합니다.");
return;
}
System.out.print("이동하면서 ");
calculate(); //상속받아서 호출 가능
battary-=1;
}
}
class TabletNotebook extends NotebookComp
{
String regstPenModel;
public TabletNotebook(String name, int initChag, String pen)
{
super(name, initChag);
regstPenModel=pen;
}
public void write(String penInfo)
{
if(battary<1)
{
System.out.println("충전이 필요합니다.");
return;
}
if(regstPenModel.compareTo(penInfo)!=0)
{
System.out.println("등록된 펜이 아닙니다.");
return;
}
System.out.println("필기 내용을 처리합니다.");
battary-=1;
}
}
class ISAInheritance
{
public static void main(String[] args)
{
NotebookComp nc=new NotebookComp("이수종", 5);
TabletNotebook tn=new TabletNotebook("정수영", 5, "ISE-241-242");
nc.movingCal();
tn.write("ISE-241-242");
}
}
# is a - 상속
has a - 넓은 의미로 보면 상속일 수 있으나 가급적 멤버변수로 두는 것이 좋다
둘 다 말이 안되면 절대 상속의 관계로 묶으면 안된다.
(문법적으로 묶을 수 있지만 논리, 개념적으로 봤을 때는 안 되는 관계이다)
ex) 상속예시
class Gun
{
int bullet; // 장전된 총알의 수
public Gun(int bnum){bullet=bnum;}
public void shut()
{
System.out.println("BBANG!");
bullet--;
}
}
class Police extends Gun
{
int handcuffs; // 소유한 수갑의 수
public Police(int bnum, int bcuff)
{
super(bnum);
handcuffs=bcuff;
}
public void putHandcuff()
{
System.out.println("SNAP!");
bullet--;
}
}
class HASInheritance
{
public static void main(String[] args)
{
Police pman=new Police(5, 3);
pman.shut();
pman.putHandcuff();
}
}
ex) 멤버변수 예시
class Gun
{
int bullet; // 장전된 총알의 수
public Gun(int bnum){bullet=bnum;}
public void shut()
{
System.out.println("BBANG!");
bullet--;
}
}
class Police
{
int handcuffs; // 소유한 수갑의 수
Gun pistol; // 소유하고 있는 권총
public Police(int bnum, int bcuff)
{
handcuffs=bcuff;
if(bnum!=0)
pistol=new Gun(bnum);
else
pistol=null;
}
public void putHandcuff()
{
System.out.println("SNAP!");
handcuffs--;
}
public void shut()
{
if(pistol==null)
System.out.println("Hut BBANG!");
else
pistol.shut();
}
}
class HasComposite
{
public static void main(String[] args)
{
Police haveGun=new Police(5, 3); // 총알 5, 수갑 3
haveGun.shut();
haveGun.putHandcuff();
Police dontHaveGun=new Police(0, 3); // 총알 0, 수갑 3
dontHaveGun.shut();
}
}
ex)
class Speaker
{
private int volumeRate;
public void showCurrentState()
{
System.out.println("볼륨 크기: "+ volumeRate);
}
public void setVolume(int vol)
{
volumeRate=vol;
}
}
class BaseEnSpeaker extends Speaker
{
private int baseRate;
public void showCurrentState()
{
super.showCurrentState();
System.out.println("베이스 크기: "+baseRate);
}
public void setBaseRate(int base)
{
baseRate=base;
}
}
class Overriding
{
public static void main(String[] args)
{
BaseEnSpeaker bs=new BaseEnSpeaker(); // 자료형을 Spearker로 바꿔도 가능
bs.setVolume(10);
bs.setBaseRate(20);
//Speaker로 바꾸는 경우 에러 발생
((BaseEnSpeaker)bs).setBaseRate(20);로 형변환해줘야 함
bs.showCurrentState();
}
}
★ ex)
class AAA
{
public void rideMethod(){System.out.println("AAA's Method");}
public void loadMethod(){System.out.println("void Method");}
}
class BBB extends AAA
{
public void rideMethod(){System.out.println("BBB's Method");}
public void loadMethod(int num){System.out.println("int Method");}
}
class CCC extends BBB
{
public void rideMethod(){System.out.println("CCC's Method");}
public void loadMethod(double num){System.out.println("double Method");}
}
class RideAndLoad
{
public static void main(String[] args)
{
AAA ref1=new CCC();
BBB ref2=new CCC();
CCC ref3=new CCC();
ref1.rideMethod(); // 결과 : CCC's Method
ref2.rideMethod(); // 결과 : CCC's Method
ref3.rideMethod();
ref3.loadMethod(); // 결과 : void Method (메소드 오버로딩)
ref3.loadMethod(1); // 결과 : int Method
ref3.loadMethod(1.2); // 결과 : double Method
}
}
ex)
문법적으로는 맞지만 이런 식으로 상위 클래스와 하위 클래스의 멤버변수 명을 동일하게 주면 헷갈릴 수 있기 때문에
절대로 상속관계에 있어 멤버변수명을 똑같게 주지 않아야 한다! 주의하기!
class AAA
{
public int num=2;
}
class BBB extends AAA
{
public int num=5;
}
class CCC extends BBB
{
public int num=7;
}
class ValReDecle
{
public static void main(String[] args)
{
CCC ref1=new CCC();
BBB ref2=ref1; //상위클래스가 하위클래스 객체 주소값 참조하는 것으로 가능
AAA ref3=ref2; // 상위클래스가 하위클래스 객체 주소값 참조하는 것으로 가능
System.out.println("CCC's ref: "+ref1.num); // 결과 : 7
System.out.println("BBB's ref: "+ref2.num); // 결과 : 5
System.out.println("AAA's ref: "+ref3.num); // 결과 : 2
}
}
ex)
class AAA
{
public int num=2;
}
class BBB extends AAA
{
public int num=5;
public void showSuperNum()
{
System.out.println("AAA's num: "+super.num); //결과 : AAA's num: 2
}
}
class CCC extends BBB
{
public int num=7;
public void showAllNums()
{
super.showSuperNum();
System.out.println("BBB's num: "+super.num); // 결과 : BBB's num: 5
System.out.println("CCC's num: "+num); //결과 : CCC's num: 7
}
}
class ShowAllReDecl
{
public static void main(String[] args)
{
CCC ref=new CCC();
ref.showAllNums();
}
}
- instanceof 연산자 : 아래 예시에서 box가 GoldPaperBox로 형변환이 가능하면 true
형변환이 안되면 false를 반환한다.
ex)
class Box
{
public void simpleWrap(){System.out.println("simple wrap");}
}
class PaperBox extends Box
{
public void paperWrap() {System.out.println("paper wrap");}
}
class GoldPaperBox extends PaperBox
{
public void goldWrap() {System.out.println("gold wrap");}
}
class InstanceOf
{
public static void wrapBox(Box box)
{
if(box instanceof GoldPaperBox)
((GoldPaperBox)box).goldWrap();
else if(box instanceof PaperBox)
((PaperBox)box).paperWrap();
else
box.simpleWrap();
}
public static void main(String[] args)
{
Box box1=new Box();
PaperBox box2=new PaperBox();
GoldPaperBox box3=new GoldPaperBox();
wrapBox(box1); // 결과 : simpleWrap
wrapBox(box2); // 결과 : paperWrap
wrapBox(box3); // 결과 : goldWrap
}
}
Q.
폴더에 있는 InstanceOf.java를 instanceof 연산자를 사용하지 않는 형태로 변경하고자 한다.
즉, 클래스의 상속관계를 그대로 유지하면서
(물론 메소드는 추가할 수 있다. 상속 관계만 그대로 유지하면 된다),
instanceof 연산자를 사용하지 않고도 동일한 실행결과를 보일 수 있어야 한다.
참고로 여러분에게 힌트가 될 수 있도록, 변경되어야 할 wrapBox 메소드를 여기 제시하겠다.
public static void wrapBox(Box box)
{
box.wrap();
}
------------------------------------------------------------
[폴더내용]
class Box
{
public void simpleWrap(){System.out.println("simple wrap");}
}
class PaperBox extends Box
{
public void paperWrap() {System.out.println("paper wrap");}
}
class GoldPaperBox extends PaperBox
{
public void goldWrap() {System.out.println("gold wrap");}
}
class InstanceOf
{
public static void wrapBox(Box box)
{
if(box instanceof GoldPaperBox)
((GoldPaperBox)box).goldWrap();
else if(box instanceof PaperBox)
((PaperBox)box).paperWrap();
else
box.simpleWrap();
}
public static void main(String[] args)
{
Box box1=new Box();
PaperBox box2=new PaperBox();
GoldPaperBox box3=new GoldPaperBox();
wrapBox(box1);
wrapBox(box2);
wrapBox(box3);
}
}
A.
class Box
{
public void simpleWrap(){System.out.println("simple wrap");}
}
class PaperBox extends Box
{
public void paperWrap() {System.out.println("paper wrap");}
}
class GoldPaperBox extends PaperBox
{
public void goldWrap() {System.out.println("gold wrap");}
}
class InstanceOf
{
public static void wrapBox(Box box)
{
box.wrap();
}
public static void main(String[] args)
{
Box box1=new Box();
PaperBox box2=new PaperBox();
GoldPaperBox box3=new GoldPaperBox();
wrapBox(box1);
wrapBox(box2);
wrapBox(box3);
}
}
'SW > Java' 카테고리의 다른 글
[필기정리]Day14 - 전화번호 관리 프로그램 문제 04단계 (0) | 2020.06.29 |
---|---|
[필기정리]Day13 - final, 상속 (0) | 2020.06.26 |
[필기정리]Day11 - 전화번호 관리 프로그램 문제 03단계 (0) | 2020.06.24 |
[필기정리]Day10 - 2차원배열, 배열 예제문제 등 (0) | 2020.06.24 |
[필기정리] Day9 - printf, 배열 등 (0) | 2020.06.22 |