티스토리 뷰

TIL/JAVA

객체지향(OOP)다형성

YEIKKI 2023. 1. 9. 13:51

다형성

-조상타입 참조변수로 자손타입객체를 다루는것(상속관계시 다형성사용가능)

 

Tv t= new Tv();   ///보통 객체를 생성할때      서로가 일치

SmartTv s= new SmartTv();// 보통 객체를 생성할때     서로가 일치


Tv t= new SmartTv(); //다형성을 이용해 조상타입참조변수로 자손객체를 다루는것 서로가 불일치

-객체와 참조변수의 타입이 일치할때와 일치하지 않을때의 차이?

 

-자손타입의 참조변수로 조상타입의 객체를 가리킬수없다.

 

(1)   Tv t= new SmartTv(); =   ok

Tv 클래스가 가지고있는 기능 5개 < 연결되어있는 객체(자손객체)에 사용가능한 기능 7개 

 

(2)   SmartTv s= new Tv(); =  error

SmartTv 가지고있는 기능 =7개 > 연결되어있는 객체(조상객체)에 사용가능한 기능 5개 

 

참조변수로 조상타입일때와 자손타입일때의 차이는?

= 참조변수로 사용할수있는 멤버갯수가 달라진다.

 

자손타입의 참조변수로 조상타입의 객체를 가리킬수 있나요?

= 허용되지않는다. 불가능

 

참조변수의 형변환

-사용할수있는 멤버갯수를 조절하는것

-조상 , 자손 관계의 참조변수로 서로 형변환가능

 

형변환시 주의사항

-형변환은 양방향으로 자유롭게 수행가능 하지만 실제 인스턴스의 개수내에서만 증가 ,감소가 이루어져야 실행 시 문제가 발생하지 않는다.

 

-형변환 실행에러 classCastException

 

 FieEngine멤버갯수 5개 --> Car멤버갯수 4개 형변환시  감소 (안전,형변환 생략가능)

Car 멤버갯수 4개---> FireEngine멤버갯수 5개 형변환시 증가 (안전하지않음,형변환 생략불가)

FireEngine f= new FireEngine(); 

Car c= (Car)f;     //OK         FieEngine멤버갯수 5개에서 --> Car로 감소 안전

FireEngine f2=(FireEngine)c;  //OK

Ambulance a= (Ambulance)f;   //에러 , 상속관계아님

Instanceof 연산자

-형변환전에 참조변수의 형변환 가능 여부 확인에 사용, 가능하면 true 반환

-형변환전에 반드시 instanceof로 확인해야함.

 

void doWork(Car c){  //Car 또는 Car의 모든 자손
if(c instanceof FireEngine){  //1. c가 가르키는 객체가 FireEngine이냐? 맞으면(true)
FireEngine fe=(FireEngine)c;  //2. 형변환 해줌
fe.water();

}

FireEngine fe= new FireEngine();

System.out.println(fe instanceof Object);  //true
System.out.println(fe instanceof Car);   // true
System.out.println(fe instanceof FireEngine); //true

Object obj= (Object)fe;  //OK
Car c= (Car) fe;         //OK

형변환이 하는 일은 타입을 맞춰줄뿐!    참조변수값도 그대로!    실제 인스턴스의 멤버갯수도 그대로!

 


매개변수의 다형성

참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄수 있다.

 

 

장점(1)  다형적 매개변수

class Product {
int price;
int bonusPoint;

Product(int price) {
this.price=price;
bonusPoint=(int)(price/10.0);
  }
}
class Tv extends Product {
Tv() {super(100);}             //super를 이용해 Tv값을 세팅
public String toString() { return "Tv";}
}

class Computer extends Product{
Computer(){ super(300);}     //super를 이용해서 Com값을 세팅
public String toString() { return "Computer";}  
}

class Buyer {      //구매자 
int money=1000;     // 가지고 있는 돈
int bonusPoint=0;   //구매를 하지않으니 0으로 초기화

void buy(Product p) {  //자손클래스 물건을 사기위한 매개변수의 다형성 사용
if(money<p.price) {
System.out.println("잔액부족 물건 구매 불가능");
return;
   }
money-=p.price;
bonusPoint+=p.bonusPoint;
System.out.println(p+"구입하셨습니다.");   //    p==p+toSTring 똑같다 , toString 생략가능!
   }
}

class Test {
public static void main(String[] args) {
Buyer b= new Buyer();     
b.buy(new Computer());   //매개변수의 다형성을 통해 컴퓨터 구매
b.buy(new Tv() );        //매개변수의 다형성을 통해 티비 구매


System.out.println("현재 잔액:"+ b.money+"원입니다.");
System.out.println("현재 보너스포인트:"+b.bonusPoint+"점입니다.");

}

 

햇갈리는 부분: b.buy(Produtct p)

b.buy(new Computer());    <==  Product p = new Computer();

                                  b.buy(p);

//이래서 new Computer() 바로쓸수있음

b.buy(new Tv()); < == Product p1= new Tv();

                                 b.buy(p1);

 

장점(2) 여러 종류의 객체를 배열로 다루기

-조상타입의 배열에 자손들의 객체를 담을수있다.

class Product{
int price;
int bonusPoint;

Product(int price) {
this.price=price;
bonusPoint=(int)price/10.0;
 }
}

class Tv extends Product{
Tv() { super(100);}

public String toString() {return"Tv";}

class Computer extends Product {
Computer(){ super(200);}
public String toString(){ return "Computer";}
}

class Phone extends Product {
Phone(){super(30);}
public String toString(){ return "Phone";}
}
class Buyer {
int money=1000;
int bonusPoint=0;

Product[] cart= new Product[3]; //구입한 제품을 저장하기 위한 배열 
int i =0;   //Product 배열에 사용될 카운터

void buy(Product p) {
if(money<p.price) {
System.out.println("잔액 부족 , 구매불가");
return;
}
money-=p.price;
bonusPoint+= p.bonusPoint;
cart[i++]=p;
System.out.println(p+" 구입하셨습니다");

 
}
void summary() {
int sum=0;
String itemList="";

for(int i=0; i<cart.length; i++) { //카트 배열 길이 만큼 for돌리기
if(cart[i]==null) break;   //카트에 아무것도 안담겨있으면 빠져나오기
sum+=cart[i].price;       //카트에 담겨져있는 물건들의 총합 / cart[i]==cart[i]+toString 
itemList+= cart[i]+" ,"; //카트에 담겨져있는 물건들 나열하기
}
System.out.println("구입하신 물품의 총금액은"+sum+"만원입니다.");
System.out.println("구입하신 제품은"+itemList+"입니다.");
  }
}

참조문헌:자바의 정석 , 남궁 성, 도우출판

 

'TIL > JAVA' 카테고리의 다른 글

객체지향(OOP)추상클래스(abstract class)  (0) 2023.01.11
객체지향(OOP)제어자  (0) 2023.01.11
객체지향(OOP)상속  (0) 2023.01.06
객체지향(OOP)메서드  (0) 2022.12.29
객체지향(OOP)Part1요약  (0) 2022.12.26