class Tv{
int x = 100;
public void power(){
System.out.println("Parent");
}
} // 부모
class smartTV extends TV{
int x = 200;
public void power(){
System.out.println("child");
}
} // 자식
Tv t = new smartTv(); // (1) 허용
smartTv s = new Tv(); // (2) 불가능
smartTv a = new smartTv();
System.out.println(t.x); // 100 출력 형변환을 해도 멤버변수는 참조변수의 타입에 따라 달라짐!!!!
t.power(); // child 출력 오버라이딩이 되었기 때문에
System.out.println(a.x); // 200 출력
t.power(); // child 출력
- 위처럼 부모 클래스보다 많은 멤버를 가진 자손 클래스는 허용이 가능하지만, class Car{
String color;
int door;
void drive(){
System.out.println("drive, brrrr~");
}
void stop(){
System.out.println("stop!!!!");
}
}
class FireEngine extends Car{
@Override
void water(){
System.out.println("water!!!");
}
}
public class Upcasting {
public static void main(String[] args) {
Car c = new Car();
FireEngine f = new FireEngine();
FireEngine f2 = null;
c = f; // Car c = (Car)f; 자손 -> 조상
// c.water(); 오류 발생
f2 = (FireEngine)c; // 조상타입 -> 자손타입
f2.water();
}
}
void test(Car c){
if(c instanceof FireEngine){ // 형변환이 가능한지 확인
FireEngine fe = (FireEngine)c; // 형변환
fe.water()
실습
(1) 부모클래스와 2개의 자식클래스 생성
(2) 메인메서드에서 다형성 실행
- b.buy(new Tv2());
- b.buy(new Computer());
(3) 독립적인 클래스 Buyer의 buy메서드에서 객체형식으로 입력받음 즉, 다형성을 한 객체 2개가 입력됨
(4) price와 bonusPoint를 부모클래스에서 가져와 계산한다
(5) 각 자식 클래스에서 Object의 toString()을 오버라이딩을 했기때문에 매개변수 입력시 오버라이딩 값 출력
class Product{
int price;
int bonusPoint;
Product(int price){
this.price = price;
bonusPoint = (int)(price/10.0); // 제품가격의 10%
}
}
class Tv2 extends Product{
Tv2(){
super(100); // 조상 클래스의 Product(int price) 호출
}
public String toString(){ // Object클래스의 toString()을 오버라이딩한다.
return "TV";
}
}
class Computer extends Product{
Computer(){
super(200);
}
public String toString(){
return "Computer";
}
}
class Buyer{
int money = 1000;
int bonusPoint = 0;
void buy(Product p){
if(money<p.price){
System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
System.out.println(p+"을/를 구입하셨습니다.");
// System.out.println(p.toString()+"을/를 구입하셨습니다."); 위에꺼랑 같은의미임
// 즉, toString()을 위에서 오버라이딩 한 값이 들어감
}
}
public class PolyArgumentTest {
public static void main(String[] args) {
Buyer b = new Buyer();
b.buy(new Tv2()); // Product p = new Tv2();
// b.buy(p) 같은 의미임
b.buy(new Computer());
System.out.println("현재 남은 돈은" + b.money +"만원입니다.");
System.out.println("현재 보너스 점수는 "+b.bonusPoint+"점입니다.");
}
}
Product[] p = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
실습
(1) 위에 실습을 배열을 통해 구현하는 것으로 부모클래스 객체의 배열안에 자손객체를 담는다
(2) 각 클래스에서 개별 객체 생성하여 설계하는 것 보다 가독성이 좋음
class Product2{
int price;
int bonusPoint;
Product2(int price){
this.price = price;
bonusPoint = (int)(price/10.0); // 제품가격의 10%
}
}
class Tv3 extends Product2{
Tv3(){
super(100); // 조상 클래스의 Product2(int price) 호출
}
public String toString(){ // Object클래스의 toString ()을 오버라이딩한다.
return "TV";
}
}
class Computer2 extends Product2{
Computer2(){
super(200);
}
public String toString(){
return "Computer";
}
}
class Audio extends Product2{
Audio(){
super(50);
}
public String toString(){
return "Audio";
}
}
class Buyer2{
int money = 1000;
int bonusPoint = 0;
Product2[] item = new Product2[10];
int i = 0; // Product2 배열에 사용될 카운터
void buy(Product2 p){
if(money<p.price){
System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
item[i++] = p; // 제품을 Product2[] item에 저장한다.
System.out.println(p+"을/를 구입하셨습니다.");
// System.out.println(p.toString()+"을/를 구입하셨습니다."); 위에꺼랑 같은의미임
// 즉, toString()을 위에서 오버라이딩 한 값이 들어감
}
void summary(){ // 구매한 물품에 대한 정보를 요약해서 보여준다.
int sum = 0; // 가격 합계
String itemList = ""; // 구입한 물품 품목
for(int i =0; i<item.length; i++){
if(item[i] == null) break;
sum += item[i].price;
itemList += item[i]+", ";
}
System.out.println("구입하신 물품의 총금액은 "+sum+"만원 입니다.");
System.out.println("구입하신 제품은 "+itemList+"입니다.");
}
}
public class PolyArgumentTestarr {
public static void main(String[] args) {
Buyer2 b = new Buyer2();
b.buy(new Tv3());
b.buy(new Computer2());
b.buy(new Audio());
b.summary();
}
}