다형성 (Polymorphism)이란?
다형성은 객체 지향 프로그래밍에서 중요한 개념 중 하나이다. 이는 한 요소(예: 메서드, 클래스)가 여러 형태를 가질 수 있는 능력을 의미한다. 다형성은 코드의 유연성과 재사용성을 높여주며, 상속, 추상화, 인터페이스와 함께 사용된다.
package basic.ch20;
public class Animal {
// 동물의 기능
// 움직인다
public void move() {
System.out.println("동물이 움직입니다.");
}
// 먹이활동
public void eating() {
System.out.println("먹이를 먹습니다.");
}
}
package basic.ch20;
public class Human extends Animal {
@Override
public void move() {
System.out.println("사람이 두발로 걷습니다.");
}
@Override
public void eating() {
System.out.println("밥을 먹습니다.");
}
public void readBooks() {
System.out.println("책을 읽습니다.");
}
}
package basic.ch20;
public class Tiger extends Animal {
@Override
public void move() {
System.out.println("호랑이가 네발로 걸어요.");
}
@Override
public void eating() {
System.out.println("호랑이가 사냥을 합니다.");
}
}
package basic.ch20;
public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Animal();
animal.move();
animal.eating();
System.out.println("-----------------------");
Animal 주소2 = new Tiger();
주소2.move();
주소2.eating();
System.out.println("-----------------------");
Animal 주소3 = new Human();
주소3.move();
주소3.eating();
System.out.println("-----------------------");
// 컴파일 시점에는 문자에 대한 것만 실행을 하고 런하면 해당하는 객체가 들어감
//
// 강제형변환 다운캐스팅
int n1 = (int)10.5;
((Human)주소3).readBooks();
}// end of main
}// end of class
업캐스팅과 다운캐스팅이란?
업캐스팅(Upcasting)과 다운캐스팅(Downcasting)은 객체 지향 프로그래밍에서 다형성을 활용할 때 사용되는 개념이다.
업캐스팅(Upcasting)
- 업캐스팅은 부모 클래스의 참조 변수로 자식 클래스의 객체를 참조하는 것을 말합니다.
- 부모 클래스의 데이터 타입으로 자식 클래스의 객체를 대입하는 것을 의미합니다.
- 업캐스팅은 자동으로 이루어집니다.
Animal animal = new Dog(); // 업캐스팅
다운캐스팅(Downcasting)
- 다운캐스팅은 부모 클래스의 참조 변수를 자식 클래스의 객체로 변환하는 것을 말합니다.
- 다운캐스팅은 명시적으로 형변환을 해야 합니다.
- 다운캐스팅은 업캐스팅된 객체가 실제로 자식 클래스의 객체일 때만 가능합니다. 그렇지 않으면 ClassCastException(예외) 이 발생할 수 있습니다.
Animal animal = new Dog(); // 업캐스팅
Dog dog = (Dog) animal; // 다운캐스팅
package basic.ch20;
public class Fruit {
String name;
int price;
public void showInfo() {
System.out.println("상품명 : " + name);
System.out.println("가격 : " + price);
}
}
package basic.ch20;
public class Peach extends Fruit {
public Peach() {
name = "복숭아";
price = 8000;
}
}
package basic.ch20;
public class Banana extends Fruit {
String origin;
public Banana() {
name = "춘식이바나나";
price = 5000;
origin = "한국";
}
public void saleBanana() {
System.out.println("바나나 가격을 할인 합니다.");
price -= 1000;
}
}
package basic.ch20;
public class FruitTest {
public static void main(String[] args) {
// 다형성
// 다양한 형태로 클래스(데이터 타입을) 바라 볼 수 있다.
Fruit fruit1 = new Banana(); // 업캐스팅된 상태
Fruit fruit2 = new Peach(); // 업캐스팅된 상태
fruit1.showInfo();
fruit2.showInfo();
System.out.println("-----------------");
// 다형을 사용하면 코드를 유연하게 작성할 수 있다.
Banana banana1 = new Banana();
Peach peach1 = new Peach();
Peach peach2 = new Peach();
// 배열
Fruit[] fruits = new Fruit[3];
fruits[0] = banana1;
fruits[1] = peach1;
fruits[2] = peach2;
System.out.println("---------------");
// fruits[0] --> 바나나
// 바나나에 속성인 origin 을 출력하시오
// 바나나에 기능인 saleBanana() 메서드를 호출하시오
// Banana bananaCasting = (Banana)fruits[0];
// bananaCasting.origin;
System.out.println(((Banana)fruits[0]).origin);
((Banana)fruits[0]).saleBanana();
System.out.println("---------------");
// 배열은 반복과 함께 많이 사용 된다.
// 0 --> 바나나
// 1 --> 복숭아
// instanceof 연산자를 알아야 해결 가능
// instanceof -->
// 실행 시점에 객체가 특정 클래스의 인스턴스인지 확인하는 키워드
for(int i = 0; i < fruits.length; i++) {
// 방어적 ...
if(fruits[i] instanceof Banana ) {
((Banana)fruits[i]).saleBanana();
} else {
fruits[i].showInfo();
}
}
} // end of main
정리
- 하나의 코드가 여러 자료형으로 구현되어 실현되는 것
- 같은 코드에서 여러 다른 실행 결과가 나옴
- 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나다
- 다형성을 잘 활용하묜 유연하고 확장성있고, 유지보수가 편리한 프로그램을 만들 수 있다.
다형성을 적용한 코드 수정(전)
package starcraft.ver04;
/**
* public
* protected -- 상속관계 설정할 수 있다.
* default
* private
*/
public class Unit {
protected String name;
protected int power;
protected int hp;
public Unit(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPower() {
return power;
}
public void setPower(int power) {
this.power = power;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
// 자신이 공격을 당합니다.
public void beAttacked(int power) {
// 방어적 코드 작성
if (hp <= 0) {
System.out.println("[" + this.name + "] 이미 사망하였습니다.");
hp = 0;
return;
}
hp -= power;
}
public void attack(Zealot z) {
System.out.println(this.name + " 이 " + z.getName() + " 을 공격합니다.");
z.beAttacked(this.power);
}
public void attack(Marine m) {
System.out.println(this.name + " 이 " + m.getName() + " 을 공격합니다.");
m.beAttacked(this.power);
}
public void attack(Zergling z) {
System.out.println(this.name + " 이 " + z.getName() + " 을 공격합니다.");
z.beAttacked(this.power);
}
public void showInfo() {
System.out.println("==== 상태창 ====");
System.out.println("이름 : " + this.name);
System.out.println("공격력 : " + this.power);
System.out.println("생명력 : " + this.hp);
}
}
다형성을 적용한 코드 수정(후)
package starcraft.ver04;
/**
* public
* default
* private
* protected - 상속관계 설정할 수 있다.
*/
public class Unit {
protected String name;
protected int power;
protected int hp;
public Unit(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPower() {
return power;
}
public void setPower(int power) {
this.power = power;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public void showInfo() {
System.out.println("---- 상태창 ----");
System.out.println("이름 : " + this.name);
System.out.println("공격력 : " + this.power);
System.out.println("생명력 : " + this.hp);
}
public void attack(Unit z) {
System.out.println(this.name + " 이 " + z.getName() + " 을 공격합니다.");
z.beAttacked(this.power);
}
// 자신이 공격을 당합니다.
public void beAttacked(int power) {
if (hp <= 0) {
System.out.println("[" + this.name + "] 이미 사망하였습니다.");
hp = 0;
return;
}
hp -= power;
}
}
728x90
'Java' 카테고리의 다른 글
인터페이스 ( interface ) 고찰 (0) | 2024.04.25 |
---|---|
인터페이스 ( interface ) (0) | 2024.04.25 |
의존 관계 ( Dependency ) (0) | 2024.04.24 |
연관 관계 ( Association )란? (1) | 2024.04.23 |
Composition ( 포함 관계 ) (0) | 2024.04.23 |