Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- this예약어
- java변수
- 형 변환
- 상수
- 자바 멀티스레딩
- 집합관계
- 인텔리제이 기초 설정
- JAVA객체지향
- function
- IntelliJ IDEA
- 메서드
- for문
- JAVA기초
- 컴파일
- continue문
- 시스템 환경 변수 편집
- 연관관계
- 반복문
- Java데이터 타입
- Thread
- break문
- 접근제어지시자
- Java
- multi-threading
- 포함관계
- 메서드 오버로딩
- OPP개념
- 생성자
- 인텔리제이 한글 깨짐 해결법
- While
Archives
- Today
- Total
최원종의 개발 블로그
다형성(Polymorphism) 본문
다형성 개념.
다형성은 하나의 데이터 타입이 다양한 형태로 바라볼 수 있는 것.
다형성은 객체 지향 프로그래밍에서 중요한 개념 중 하나이다.
이는 한 요소(ex: 메서드, 클래스)가 여러 형태를 가질 수 있는 능력을 의미한다.
다형성은 코드의 유연성과 재사용성을 높여주며, 상속, 추상클래스, 인터페이스와 함께 사용됨.
다형성 코드
package com.tenco.polymorphism;
import com.tenco.Inheritance.A;
public class Animal {
public void move() {
System.out.println("동물이 움직입니다");
}
public void eating() {
System.out.println("먹이를 먹습니다");
}
}//end of animal class
class Human extends Animal {
@Override //주석 + 힌트 자식클래스에서 부모클래스 재정의 하는 것을 오버라이드라고 함
public void move() {
System.out.println("사람이 두 발로 걷습니다.");
}
@Override
public void eating() {
System.out.println("밥을 먹습니다");
}
public void readBooks() {
System.out.println("책을 읽습니다");
}
}//end of Human class
class Tiger extends Animal {
@Override
public void move() {
System.out.println("호랑이가 살금살금 네 발로 걸어요");
}
@Override
public void eating() {
System.out.println("호랑이가 사냥을 합니다");
}
}
-AnimalMain
package com.tenco.polymorphism;
/**
* 하나의 데이터 타입을 다양한 형태로 바라 보는 것(다형성)
* 상속 관계
*/
public class AnimalMain {
public static void main(String[] args) {
Animal animal = new Animal();
animal.move();
animal.eating();
System.out.println("-----------------");
// 다형성 - Animal 과 Tiger는 상속관계 이기 때문기 때문에 다형성이 적용이 되고
// Tiger 타입은 Animal 타입으로 바라 볼 수 있다.
Animal animalTiger = new Tiger();
animalTiger.move();
animalTiger.eating();
// 부모 클래스 타입으로 자식 객체를 생성 했을 때..
// [[컴파일 시점]]에는 부모 타입에 메서드가 있는지 없는지 여부만 확인한다.
// 하지만 실행 시점에는 생성성 객체의 메서드가 먼저 있는지 확인하다.
System.out.println("---------------------");
Animal animalHuman = new Human();
animalHuman.move();
animalHuman.eating();
// animalHuman.readBooks();
// 왜 readBooks() 오류가 날까?
// 컴파일 시점에는 Animal 타입만 확인하기 때문에
// 부모 클래스인 Animal 클래스 안에는 readBooks() 메소드가 없기 때문이다
System.out.println("------------------------------");
Human human = new Human();
human.move();
human.eating();
human.readBooks();
} // end of main
}
업캐스팅과 다운 캐스팅
업캐스팅과 다운캐스팅은 객체 지향 프로그래밍에서 다형성을 활용할 때 사용되는 개념.
업캐스팅(Upcasting)
- 업캐스팅은 부모 클래스의 참조변수로 자식 클래스의 객체를 참조하는 것
- 부모 클래스의 데이터 타입으로 자식 클래스의 객체를 대입하는 것을 의미.
- 업캐스팅은 자동으로 이루어진다
Animal animal = new Dog(); // 업캐스팅
다운캐스팅(Downcasting)
- 다운캐스팅은 부모 클래스의 참조 변수를 자식 클래스의 객체로 변환하는 것을 의미
- 다운캐스팅은 명시적으로 형변환을 해야 한다.
- 다운캐스팅은 업캐스팅된 객체가 실제로 자식 클래스의 객체일 때만 가능하다.
- 그렇지 않으면 ClassCastException(예외)이 발생할 수 있다.
Animal animal = new Dog(); // 업캐스팅
Dog dog = (Dog) animal; // 다운캐스팅
코드
package com.tenco.polymorphism;
/**
* 하나의 데이터 타입을 다양한 형태로 바라 보는 것(다형성)
* 상속 관계
*/
public class AnimalMain {
public static void main(String[] args) {
Animal animalTiger = new Tiger(); // 업캐스팅된 상태
// ** 다운 캐스트 해보기 **
Tiger tiger = (Tiger) animalTiger;
System.out.println("---------------------");
Animal animalHuman = new Human();
animalHuman.move();
animalHuman.eating();
// 다운 캐스팅 해보기
Human humanDownCasting = (Human) animalHuman;
humanDownCasting.readBooks();
((Human)animalHuman).readBooks(); // 축약해서 호출 가능
System.out.println("------------------------------");
// 강제 형 변환
int a = (int)1.1;
} // end of main
}
-FruitMain
package com.tenco.polymorphism;
import com.tenco.Inheritance.B;
public class FruitMain {
public static void main(String[] args) {
Fruit fruit1 = new Banana();//업캐스팅된 상태 -> 부모타입으로 자식 객체를 생성
Fruit fruit2 = new Peach();
fruit1.showInfo();
fruit2.showInfo();
System.out.println("----------------");
//바나나 원산지만 콘솔 창에 출력하시오
String origin = ((Banana) fruit1).origin;
System.out.println("바나나 원산지 : " + origin);
System.out.println("-----------------");
//키워드 - 업캐스팅된 상태에서 사용할 수 있는 instanceof 연산자를 사용해 보자.
//현재 생성된 객체의 타입을 확인할 대 사용하는 연산자
if (fruit1 instanceof Banana) {
System.out.println("fruit1 타입의 샐제 자식 타입은 바나나 타입입니다.");
}
if (fruit2 instanceof Banana) {
System.out.println("fruit2 타입의 실제 자식 타입은 바나나 타입입니다");
String resultOrigin = ((Banana) fruit2).origin;
} else if (fruit2 instanceof Peach) {
System.out.println("fruit2 타입의 실제 자식 타입은 복숭아 타입입니다");
} else {
System.out.println("그냥 과일 타입입니다");
}
}
}
-다형성 활용
package com.tenco.polymorphism;
public class Banana extends Fruit {
// String name;
// int price;
String origin; //바나나 클래스만 가지고 있음
public Banana() {
this.name = "델몬트 바나나";
this.price = 5_000;
this.origin = "필리핀";
}
public void sale() {
System.out.println("--바나나 할인 기간--");
System.out.println("할인된 가격 : " + (this.price - 1000));
}
}
-EMart
package com.tenco.polymorphism;
import com.tenco.Inheritance.B;
public class EMart {
public static void main(String[] args) {
Banana[] bananas = new Banana[10];
Peach[] peaches = new Peach[10];
//---------------------------------------
//다형성에 장점 활용
Fruit[] fruits = new Fruit[4];
fruits[0] = new Banana();
fruits[1] = new Peach();
fruits[2] = new Banana();
fruits[3] = new Peach();
for (int i = 0; i < fruits.length; i++) {
fruits[i].showInfo();
// 바나나 타입인지 검사
if (fruits[i] instanceof Banana) {
((Banana) fruits[i]).sale();
}
}
}
}
다형성 특징
- 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
- 같은 코드에서 여러 다른 실행 결과가 나온다
- 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나
- 다형성을 잘 활용하면 유연하고 확장성 있고, 유지보수가 편리한 프로그램을 만들 수 있다
- (.) 연산자 여러 번 사용해 보기
1. 포함관계
package com.tenco.polymorphism;
class A {
B b = new B();
}
class B {
C c = new C();
}
class C {
D d = new D();
}
class D {
void showInfo() {
System.out.println("D 클래스의 showInfo 메서드 호출");
}
}
public class Main {
public static void main(String[] args) {
// . 점 연산자의 여행
// A , B , C , D 설계
// 1. 가장 바깥쪽에 있는 객체 생성
A a = new A();
// 2. 깊숙이 들어있는 D 의 메서드 호출
// a(의) -> b(의) -> c(의) -> d(의) -> shoInfo()
// 최종 결과 코딩
// a.b.c.d.shoInfo();
// "D 클래스 showInfo() 를 호출 했습니다."
a.b.c.d.showInfo();
a = null;
}
}
2. 연관관계
package com.tenco.polymorphism;
class A {
// B b = new B();//포함관계
B b;
//외부에서 주입 받는 방법 2가지
//1. 생성자 주입<- 많이 쓰는 방법
//2. 메서드 통해서 주입
public A(B b) {
this.b = b;
}
}
class B {
// C c = new C();
C c;
public B(C c) {
this.c = c;
}
}
class C {
// D d = new D();
D d;
public C(D d) {
this.d = d;
}
}
class D {
public void showInfo() {
System.out.println("D클래스 showInfo()를 호출했습니다");
}
}
public class Main {
public static void main(String[] args) {
//.점 연산자의 여행
//A,B,C,D설계
//1.가장 바깥쪽에 있는 객체 생성
D d = new D();
C c = new C(d);
B b = new B(c);
A a = new A(b);
//2. 깊숙이 들어있는 D의 메서드 호출
//a(의) -> b(의) ->(c)의 -> d(의) -> showInfo()
//최종 결과 코딩
a.b.c.d.showInfo();
//"D클래스 showInfo()를 호출했습니다
//연관 관계로 코드를 수정해 주세요
//포함 --> 연관 --> 외부에서 주입 받도록 해야하고 독립적으로 객체들이 힙에
//존재할 수 있게 설계
}
}
'Java > Java 객체지향' 카테고리의 다른 글
| 인터페이스(interface) (0) | 2026.03.06 |
|---|---|
| 추상 클래스(abstract class) (0) | 2026.03.06 |
| 포함관계와 집합관계 (0) | 2026.03.04 |
| 연관관계(Association) (0) | 2026.03.04 |
| 상속과 접근제어 지시자 (0) | 2026.03.04 |


