1. 다형성
- 여러가지 형태를 가질 수 있는 능력
- 조상 타입 참조 변수로 자손 타입 객체를 다루는 것
-> 타입이 불일치한 것도 괜찮다.
Tv t = new SmartTv();
조상 자손
Tv t 조상의 멤버변수 4개
SmartTv 자손의 멤버변수 5개
이면 t는 4개만 사용할 수 있다.
* 자손 타입의 참조변수로는 조상 타입의 객체를 가리킬 수 없다.
SmartTv s = new Tv(); // 에러
2. 참조변수의 형변환
- 사용할 수 있는 멤버의 갯수를 조절하는 것
- 조상 자손 관계의 참조변수는 서로 형변환 가능
Car의 자손 FireEngine 클래스가 있고
Car의 멤버변수 4개 , FireEngine 의 멤버변수 5개 일때,
FireEngine f = new FireEngine();
Car c = (Car)f; // 조상인 Car타입으로 형변환(생략가능)
FireEngine f2 = (FireEngine)c; //자손인 FireEngine타입으로 형변환(생략불가)
변수 f와 c 둘다 FireEngine이라는 객체를 가리키게 되지만,
조상타입 Car 타입의 참조변수 c로 담을 수 있는 건 변수 4개밖에 안된다.
f 변수는 5개이다.
따라서 형변환을 통해 개수를 4개->5개 / 5개->4개 바꿀 수 있다는 걸 알 수 있다.
3. 매개변수의 다형성
다형성의 장점
1. 다형적 매개변수
2. 하나의 배열로 여러종류 객체 다루기
매개변수의 다형성
- 참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.
* 오버로딩 : 메서드 이름 같은데, 매개변수 타입이 다른것
메서드를 계속 오버로딩 하면 코드도 길어지고 오류날 가능성이 많아진다.
아래는 두 코드는 같은 코드이다.
오리지널 방식은 참조변수가 있는 2문장으로 쓰는 것이다.
Product p = bew Tv1();
b.buy(p);
위 문장을 1문장으로 줄일 수 있다. 하지만, 참조변수 p가 없어서 메서드 안에서 Tv1을 사용할 수 없다.
b.buy(new Tv1());
예제소스
//조상클래스 Product
class Product {
int price; // 제품의 가격
int bonusPoint; // 제품구매 시 제공하는 보너스점수
Product(int price) { // 조상클래스 생성자에 100이 들어가게됨
this.price = price;
bonusPoint = (int)(price/10.0); // 보너스점수는 제품가격의 10%
}
}
//Product의 자식클래스
//Tv1 클래스와 Computer 클래스는 각각 Product 클래스를 상속받으며,
//상속을 받으면 조상 클래스의 변수와 메소드를 그대로 사용할 수 있습니다.
class Tv1 extends Product {
Tv1() {
// 조상클래스의 생성자 Product(int price)를 호출한다.
super(100); // Tv의 가격을 100만원으로 한다.
}
// Object클래스의 toString()을 오버라이딩한다.
public String toString() { return "Tv"; }
}
// Computer 클래스는 가격이 200인 컴퓨터 제품을 나타내며,
//이를 문자열로 표현할 때는 "Computer"라는 문자열이 출력됩니다.
//이 클래스는 Product 클래스의 멤버 변수와 메소드를 그대로 상속받아 사용할 수 있습니다.
class Computer extends Product {
Computer() { super(200); } //조상 클래스 생성자에 200이 들어가게됨
public String toString() { return "Computer"; }
// Computer 객체를 문자열로 표현할 때 "Computer"라는 문자열이 출력된다는 의미
}
//Buyer 클래스
class Buyer { // 고객, 물건을 사는 사람
int money = 1000; // 소유금액
int bonusPoint = 0; // 보너스점수
void buy(Product p) { //Product p에는 newTv1, new Computer 들어갈 수 있음
if(money < p.price) {
System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
return;
}
money -= p.price; // 가진 돈에서 구입한 제품의 가격을 뺀다. 1000-100-200 = 700만
bonusPoint += p.bonusPoint; // 제품의 보너스 점수를 추가한다. 10 + 20 = 30점
System.out.println(p + "을/를 구입하셨습니다.");
//참조변수와 문자열 결합할때는 참조변수p의 toStirng을 호출한다.
}
}
class Ex7_8 {
public static void main(String args[]) {
//Buyer 객체 생성
Buyer b = new Buyer(); //1000원 있음
//Buyer의 자손 클래스들 호출할 수 있음
b.buy(new Tv1()); //void buy(Product p)
b.buy(new Computer()); //void buy(Product p)
System.out.println("현재 남은 돈은 " + b.money + "만원입니다.");
System.out.println("현재 보너스점수는 " + b.bonusPoint + "점입니다.");
}
}
콘솔값
Tv을/를 구입하셨습니다.
Computer을/를 구입하셨습니다.
현재 남은 돈은 700만원입니다.
현재 보너스점수는 30점입니다.
4. 여러 종류의 객체를 배열로 다루기
자바의정석 강의 참고 : https://www.youtube.com/watch?v=pcd29KSrql8&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=85
- 조상타입의 배열에 자손들의 객체를 담을 수 있다.
Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();
이 코드를 배열로 바꾸면 아래와 같은 코드가 된다.
Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
예제
sum은 price 가격의 누적
itemList는 cart에 저장된 객체의 이름 반환 Tv, Computer, Audio....
'java' 카테고리의 다른 글
[JAVA] foreach문 (0) | 2023.02.20 |
---|---|
[java] Generics(제네릭), Collection(컬렉션)-list, map (0) | 2023.02.20 |
java) row_number()over, partition, substr, order by (0) | 2023.02.17 |
Java) String.format 을 이용한 문자열 형식 설정하기 (0) | 2023.02.16 |
[JAVA] forEach문 사용이유 (0) | 2023.02.10 |
댓글