다형성(polymorphism)

DEVELOPERS_Ivan ㅣ 2023. 8. 9. 11:01

다형성
● 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
● 같은 코드에서 여러 다른 실행 결과가 나옴
● 정보 은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나임
● 다형성을 잘 활용하면 유연하고 확장성 있고, 유지 보수가 편리한 프로그램을 만들 수 있음

업캐스팅

다운캐스팅
주의 할 점
다운캐스팅을 할 때는 반드시 원래의 하위 클래스 타입으로 변환 가능한지
instanceof 연산자로 확인하는 것이 안전합니다.
만약 객체가 해당 하위 클래스의 인스턴스가 아닌 경우에는 ClassCastException이 발생할 수 있다.

instanceof 연산자

//20230809_다형성 #1

package ch05;

 

public class Animal {

public void move() {

System.out.println("동물이 움직입니다.");

}

 

public void eating() {

System.out.println("동물이 먹이를 먹습니다..");

}

} // end of class

 

class Tiger extends Animal {

@Override

public void move() {

System.out.println("호랑이가 네 발로 움직입니다.");

 

}

 

@Override

public void eating() {

System.out.println("호랑이가 사냥을 합니다");

}

 

}

 

class Human {

 

public void move() {

System.out.println("사람이 두 발로 걸어 다닙니다.");

}

 

public void eating() {

System.out.println("밥을 먹습니다.");

}

 

public void readbooks() {

System.out.println("사람이 책을 읽습니다.");

}

}

//20230809_다형성 #1

package ch05;

 

public class MainTest1 {

 

public static void main(String[] args) {

 

Animal animal1 = new Animal();

Tiger tiger1 = new Tiger();

Human human1 = new Human();

 

// 다형성을 적용

Animal animal2 = new Tiger();

 

Animal[] arrayAnimals = new Animal[10];

arrayAnimals[0] = tiger1;

arrayAnimals[1] = animal1;

// arrayAnimals[2] = human1;

// Animal animal3 = new Human();

// 여기까지는 컴파일 시점에서 확인되는 부분을 확인

 

System.out.println("----------------------------");

tiger1.move();

tiger1.eating();

System.out.println("----------------------------");

human1.move();

human1.eating();

System.out.println("----------------------------");

animal2.move();

human1.eating();

}

 

}


//20230809_다형성 #3

package ch05;

 

public class Fruit {

 

String name;

int price;

 

public Fruit(String name, int price) {

this.name = name;

this.price = price;

}

 

public void showInfo() {

System.out.println("상품명 : " + name);

System.out.println("가격 : " + price);

}

} // end of class

//20230809_다형성 #3

package ch05;

 

public class Banana extends Fruit {

String origin;

 

public Banana(String name, int price) {

super(name, price);

origin = "필리핀";

}

 

} // end of class

//20230809_다형성 #3

package ch05;

 

public class Peach extends Fruit {

 

public Peach(String name, int price) {

super(name, price);

}

} // end of class

//20230809_다형성 #3

package ch05;

 

public class FruitMaintTest1 {

 

public static void main(String[] args) {

 

// 다형성

// ! 용어 - 업캐스팅

Fruit fruit1 = new Banana("델몬트바나나", 2_000);

Fruit fruit2 = new Peach("청도복숭아", 3_000);

 

fruit1.showInfo();

fruit2.showInfo();

// 바나나 객체에 origin 변수 값을 출력해 보자.

// 업캐스팅 된 상태에서는 컴파일 시점만 확인을 한다.

 

// System.out.println(fruit1.origin); 오류 확인

// ?? 컴파일 시점에 어떻게 origin 이라는 변수를 출력할까?

 

// 1단계 - 다운 캐스팅

Banana banana1 = ((Banana) (fruit1));

System.out.println(banana1.origin);

System.out.println("---------------");

 

// 2단계 - 다운 캐스팅

String checkOrigin = ((Banana) (fruit1)).origin;

System.out.println(checkOrigin);

 

} // end of main

 

} // end of class

//20230809_다형성 #3

package ch05;

 

public class FruitMainTest2 {

 

public static void main(String[] args) {

 

Fruit[] fruits = new Fruit[5];

fruits[0] = new Peach("복숭아1", 3_000);

fruits[1] = new Banana("델몬트바나나", 2_000);

fruits[2] = new Peach("복숭아2", 3_000);

 

// 배열은 보통 반복문과 함께 많이 사용한다.

for (int i = 0; i < fruits.length; i++) {

if (fruits[i] != null) {

fruits[i].showInfo();

// 만약 바나나라면 원산지 정보도 함께 출력 하시오.

if (fruits[i] instanceof Banana) {

String checkOrigin = ((Banana) fruits[i]).origin;

System.out.println("원산지 : " + checkOrigin);

}

}

 

}

} // end of main

 

} // end of class


//20230809_다형성 #4(랜덤게임 프로그램 다시 만들어보기)

 

package ch06;

 

import java.util.Random;

 

public class RandomGame {

 

public static void main(String[] args) {

Random random = new Random();

int selected = random.nextInt(3) + 1;

String[] strings = new String[3];

strings[0] = "곰인형";

strings[1] = "아이폰";

strings[2] = "호돌이";

System.out.println(strings[selected]);

 

} // end of main

} // end of class


//20230809_다형성 #5 기초 다시 만들어보기

 

package ch06;

 

// 상속받는다.

public class Bird extends Animal {

@Override // 자동완성 오버라이드

public void makeSound() {

 

System.out.println("새가 지저귀고 있습니다.");

 

}

 

public void fly() {

 

System.out.println("새가 날아갑니다.");

 

}

}

//20230809_다형성 #5 기초 다시 만들어보기

 

package ch06;

 

public class Animal {

public void makeSound() {

System.out.println("동물이 소리를 내고 있습니다.");

}

}

//20230809_다형성 #5 기초 다시 만들어보기

 

package ch06;

 

public class CastingExample {

 

public static void main(String[] args) {

 

// 다형성, 업 캐스팅(Up casting)

// 업 캐스팅은 하위 클래스의 객체를 상위 클래스 타입으로

// 변환 하는 것을 말한다. 이 경우에는 데이터 손실이 없다.

// 업 캐스팅은 자동적으로 이루어지므로 별도의 형 반환 연산자가 필요없다.

 

// 상위 클래스로 변환 시켜줌

Animal animal = new Bird();

// animal.fly();

 

// 다형성, 다운 캐스팅(down casting)

// 다운 캐스팅은 업 캐스팅된 객체를 다시 원래의 하위

// 클래스 타입으로 변환하는 것을 말한다,

// 다운 캐스팅은 수동적으로 형 변환 연산자를 사용하여 이루어진다.

// 업 캐스팅된 객체를 하위 클래스에 메서드나 속성을 사용하기 위해 사용한다.

Bird bird = (Bird)animal;

bird.fly();

 

// 배열을 활용

Animal[] animals = new Animal[3];

animals[0] = new Animal();

animals[1] = new Bird();

animals[2] = new Animal();

 

// foreach 문 사용중

// 0 -- Animal --> if --> false

// 1 -- Bird --> if --> true

// 2 -- Animal --> if --> false

for (Animal a : animals) {

a.makeSound();

// a.fly(); 데이터 타입을 확인하고 싶다면 instanceof 연산자 활용

if(a instanceof Bird) {

Bird targeBird = (Bird)a;

targeBird.fly();

}

System.out.println("-----------------");

}

// // indexfor 문 - 우리가 사용하는 i로 연산이 가능함

// for (int i = 0; i < animals.length; i++) {

//

// }

 

} // end of main

 

} // end of class


// 20230809_상속 #6 설계(상속과 다형성을 이용하여 코드를 줄일 수 있음)

 

package startcraft;

 

public class MainTest1 {

 

public static void main(String[] args) {

Zealot zealot1 = new Zealot("질럿1");

Marine marine1 = new Marine("마린1");

 

zealot1.attack(marine1);

marine1.showInfo();

 

}

}

'Java' 카테고리의 다른 글

[java] 추상 클래스  (0) 2023.08.10
[java] 기초 연습  (0) 2023.08.10
[java] 상속  (0) 2023.08.07
[Java] 배열  (0) 2023.08.04
[java] 대중교통 이용 프로그램 만들기  (0) 2023.08.03