다형성(polymorphism)
- 객체지향 프로그램 4대 특징 중 하나. - 상속과 연관성이 많음.
- 다형성의 사전적 의미 - 같은 종의 생물이지만 모습이나 특징이 고유한 성질을 가지고 있는 것.
- 여러가지 모습으로 해석될 수 있는 형태를 의미함.
- 여러가지 형태를 가질 수 있는 능력을 말함.
- 하나의 메서드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것.
- 하나의 사물(객체)을 다양한 타입으로 선언하고 이를 이용할 수 있는 성질.
- 하나의 참조변수로 여러 타입의 객체를 참조할 수 있는 것.
==> 부모타입의 참조변수로 자식타입의 객체를 다룰 수 있는 것이 다형성의 특징.
단, 자식 클래스에서 상속을 받은 멤버들만 접근할 수 있고,
자식 클래스에서 만들어진 멤버들에는 접근할 수 없음.
예) 부모타입의 참조변수로 자식의 멤버를 호출.
- 부모 타입의 참조변수로 자식 타입의 인스턴스를 참조할 수 있지만,
반대로 자식타입의 참조변수로 부모타입의 인스턴스를 참조할 수는 없음.
instanceof 연산자
- 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보는 연산자.
- 연산결과로 boolean 값(true / false)를 반환.
예) 참조변수 instanceof 클래스명(타입)
if(a instanceof Car) : 참조변수 a의 타입이 Car 클래스 타입인지 체크함.
==> true이면 Car 인스턴스 타입이고 false이면 Car 인스턴스 타입이 아니다.
예시)
package Polymorphism;
class A {}
class B extends A {}
class C extends A {}
class D extends B {}
class E extends C {}
public class Ex04_Main {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
E e = new E();
A b1 = new B(); // B클래스는 A클래스를 상속받았으므로, 변수 b1는 A이다.
A c1 = new C(); // C클래스는 A클래스를 상속받았으므로, 변수 C1는 A이다.
A d1 = new D(); // D클래스는 A클래스를 상속받은 B를 상속 받았으므로, 변수 d1는 A이다.
A e1 = new E(); // E클래스는 A클래스를 상속받은 C를 상속 받았으므로, 변수 e1는 A이다.
B d2 = new D(); // D클래스는 B클래스를 상속 받았으므로, 변수 d2는 B이다.
C e2 = new E(); // E클래스는 C클래스를 상속 받았으므로, 변수 e2는 C이다.
// instanceof : 두 개의 객체가 같은 지 물어보는 연산자
if(d instanceof B) {
// 참조변수 d의 타입이 B 클래스 타입인지 체크
// 맞으면 true 출력
System.out.println("true"); }
// 아니면 false 출력
else {
System.out.println("false"); }
}
}
결과
true
예제 01)
다형성을 이용해서 Animal 이라는 추상클래스를 만들고,
이에 강아지, 고양이 등의 자손 타입 클래스를 생성하여 프로그램을 구현하자
package Polymorphism;
interface Animal {
//추상메소드 구현
void sound();
}
class Dog implements Animal{
//부모에서 상속받은 메소드
@Override
public void sound() {
System.out.println("멍멍멍");
}
//자식의 메소드
void output() {
System.out.println("출력용 메소드입니다.");
}
}
class Cat implements Animal{
//부모에서 상속받은 메소드
@Override
public void sound() {
System.out.println("냐옹");
}
}
public class Ex01_Animal {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound();
Cat cat = new Cat();
cat.sound();
// 다형성을 이용하여 객체를 생성
Animal dog1 = new Dog(); // 강아지(dog)은 동물(Animal)이다. => 업캐스팅
dog1.sound();
// 자식클래스에서 만들어진 멤버에는 접근 불가
// 부모에는 없는 자식의 멤버는 호출할 수 없다.
// dog1.output(); ==> error 발생
Animal cat1 = new Cat(); // 고양이(cat)는 동물(Animal)이다. => 업캐스팅
cat1.sound();
// 자식에는 있는 멤버가 부모에는 없을 수 있기 때문에 자식이 부모의 객체로는 생성 불가.
//Dog dog2 = new Animal(); ==> error 발생, 동물(Animal)은 강아지(dog)다. 라는 명제가 당연히 거짓인 것 처럼.
}
}
예제02)
다형성을 이용해서 오버워치 게임을 만들어보자.
package Polymorphism;
import java.util.Scanner;
// 부모클래스_OverWatch
interface OverWatch {
// 전부다 추상메서드이니 interface로 선언한다.
void name();
void leftClick();
void rightClick();
void shiftButton();
void eButton();
void qButton();
}
// 자식클래스
// 메이
class Mei implements OverWatch {
@Override
void name() {
System.out.println("이 름 : 메이");
}
@Override
void leftClick() {
System.out.println("왼쪽 버튼 : 냉각중");
}
@Override
void rightClick() {
System.out.println("오른쪽 버튼 : 고드름");
}
@Override
void shiftButton() {
System.out.println("Shift 버튼 : 급속 빙결");
}
@Override
void eButton() {
System.out.println("e 버튼 : 빙벽");
}
@Override
public void qButton() {
System.out.println("q 버튼 : 눈보라");
}
}
class Gengi implements OverWatch {
@Override
void name() {
System.out.println("이 름 : 겐지");
}
@Override
void leftClick() {
System.out.println("왼쪽 버튼 : 표창던지기");
}
@Override
void rightClick() {
System.out.println("오른쪽 버튼 : 표창 3개 던지기");
}
@Override
void shiftButton() {
System.out.println("Shift 버튼 : 돌진");
}
@Override
void eButton() {
System.out.println("e 버튼 : 칼로 막기");
}
@Override
void qButton() {
System.out.println("q 버튼 : 칼로 썰기(죽이기)");
}
}
// 맥크리
class Mccree implements OverWatch {
@Override
void name() {
System.out.println("이 름 : 맥크리");
}
@Override
void leftClick() {
System.out.println("왼쪽 버튼 : 피스키퍼");
}
@Override
void rightClick() {
System.out.println("오른쪽 버튼 : 모든 총알 발사");
}
@Override
void shiftButton() {
System.out.println("Shift 버튼 : 구르기");
}
@Override
void eButton() {
System.out.println("e 버튼 : 섬광탄");
}
@Override
void qButton() {
System.out.println("q 버튼 : 황야의 무법자");
}
}
public class Ex02_Game {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
OverWatch watch = null;
System.out.println("플레이할 캐릭터 선택(1.메이 / 2.겐지 / 3.맥크리)");
int bunho = sc.nextInt();
if(bunho == 1) {
watch = new Mei(); //다형성
} else if(bunho == 2) {
watch = new Gengi(); //다형성
} else if(bunho == 3) {
watch = new Mccree(); //다형성
}
watch.name();
watch.leftClick();
watch.rightClick();
watch.shiftButton();
watch.eButton();
watch.qButton();
sc.close();
}
}
재정의 된 메서드가 호출된다.
'Back-End > Java' 카테고리의 다른 글
[Java] 접근지정자(접근제어자) 권한 (0) | 2021.08.18 |
---|---|
[Java] 자바 빈(Java Bean), API, 패키지(package) (0) | 2021.08.18 |
[Java] 인터페이스(Interface) (0) | 2021.08.17 |
[Java] 상속_추상클래스(abstracts class) (0) | 2021.08.17 |
[Java] 상속_메소드 재정의(method overriding) (0) | 2021.08.17 |
댓글