※ 본문은 혼자 공부한 내용을 기록한 글입니다. 오개념이 있다면 댓글로 알려주세요!
[ 1 ] 다형성(Polymorphism)이란?
다형성에 대한 정의가 여러가지 글, 영상자료마다 다르고 다양해서 하나로 정의하기 어려웠다. 이에 필자가 찾은 모든 정의를 정리하고자 한다.
(1) 하나의 타입에 실행결과가 각기 다른 여러 객체를 대입할 수 있는 것
(2) 하나의 객체가 여러가지 타입을 가질 수 있는 것
(3) 하나의 메소드나 클래스가 다양한 방법으로 동작하는 것
세 정의는 미묘하게 다르지만, 공통된 부분이 있다. 바로 "하나"의 무엇이 "여러가지, 다양한" 것을 할 수 있고, 될 수 있음을 나타내고 있다.
이 공통된 부분에 초점을 두고 다형성을 정리해보자.
[ 2 ] 메소드의 다형성
하나의 메소드가 다양한 방법으로 동작하는 것에는 Overriding과 Overloading이 있다. 단, Overloading이 다형성인지에 대해서는 이견이 있다고 한다.
Overriding의 경우 오라클 튜토리얼과 w3schools에서도 다형성의 예시로 들고 있고, 클래스의 다형성에서도 핵심 내용이므로 숙지하도록 하자.
[Java] Overriding, Overloading
※ 본문은 혼자 공부한 내용을 기록한 글입니다. 오개념이 있다면 댓글로 알려주세요! [ 1 ] Overriding 상속이란 자식 클래스에서 부모 클래스의 필드와 메소드를 물려받아 사용할 수 있는 것을 의
krchoish.tistory.com
[ 3 ] 클래스의 다형성
Java에서는 다형성을 통해
(1) 하나의 타입에 실행결과가 각기 다른 여러 객체를 대입할 수 있는 것
(2) 하나의 객체가 여러가지 타입을 가질 수 있는 것
를 실현할 수 있다.
Java는 이러한 다형성을 위해 부모 클래스 타입의 참조변수가 자식 클래스의 인스턴스를 참조하는 것을 허용한다.
(이는 Java가 자식 클래스 인스턴스가 부모 클래스로 자동타입변환하는 것을 허용함으로써 가능한 것이다)
class Parent {
}
class Child extends Parent {
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
Parent p1 = new Child();
}
}
즉, 위 소스코드처럼 부모 클래스 타입의 변수인 p1이 Child 인스턴스를 참조할 수 있음을 의미한다.
부모 클래스 타입 변수가 자식 클래스 인스턴스를 참조한 후에는 자식 클래스를 참조하고 있음에도 불구하고, 부모 클래스 멤버에만 접근할 수 있도록 한정된다. 즉, 부모 클래스에는 없고 자식 클래스에만 있는 멤버에는 접근할 수 없다.
package polymorphism;
class Parent {
public void a() {
System.out.println("Parent.a()");
}
}
class Child extends Parent {
public void b() {
System.out.println("Child.b()");
}
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
Parent p1 = new Child();
p1.a(); // Parent 멤버이므로 사용 가능
p1.b(); // Parent 멤버 아니므로 사용 불가능
}
}
즉, 위 소스코드에서 메소드 b는 Parent의 멤버가 아니므로 변수 p1이 접근할 수 없다.
단, 자식 클래스에서 Overriding한 메소드라면 Overriding된 메소드가 대신 호출된다.
class Parent {
public void a() {
System.out.println("Parent.a()");
}
}
class Child extends Parent {
public void a() {
System.out.println("Child.a()");
}
public void b() {
System.out.println("Child.b()");
}
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
Parent p1 = new Child();
p1.a(); // Child의 a 메소드 접근 가능
}
}
변수 p1은 원래 Parent 클래스의 멤버에만 접근할 수 있으나, 현재 Child 클래스가 Parent 클래스의 a 메소드를 Overriding 하고 있으므로 Child 클래스의 a 메소드가 대신 호출된다.
p1.a(); 의 실행결과로도 Child 클래스의 a 메소드가 대신 호출되었음을 확인할 수 있다.
그렇다면 클래스의 다형성이 우리에게 주는 이점은 무엇일까?
[ 3 - 1 ] 필드의 다형성
필드의 타입을 부모 클래스로 설정하여 다형성을 통해 여러가지 실행 결과를 도출할 수 있다.
예를 들어, 게임 배틀그라운드에는 수많은 종류의 총이 있고, 한 명의 플레이어가 두 개의 총을 소지할 수 있다. 만약, 한 명의 플레이어가 M4와 AK47을 소지하고 있다고 가정할 때 다음과 같이 소스코드를 작성하면 어떤 문제가 있을까?
class M4 {
void m4shot() {
System.out.println("5.56mm 탄 발사");
}
}
class Ak47 {
void ak47shot() {
System.out.println("7.62mm 탄 발사");
}
}
class Player {
M4 firstWeapon;
Ak47 secondWeapon;
void attack() {
this.firstWeapon.m4shot();
this.secondWeapon.ak47shot();
}
}
플레이어가 기존의 총을 버리고 새로운 종류의 총을 얻을 때마다 필드의 타입을 변경해야 하고, attack 메소드 내부의 내용도 수정해야 한다는 문제가 발생한다. 이는 굉장히 비효율적이다.
class Weapon {
void shot() {
System.out.println("총알 발사");
}
}
class M4 extends Weapon {
void shot() {
System.out.println("5.56mm 탄 발사");
}
}
class Ak47 extends Weapon {
void shot() {
System.out.println("7.62mm 탄 발사");
}
}
class Player {
Weapon firstWeapon;
Weapon secondWeapon;
void attack() {
this.firstWeapon.shot();
this.secondWeapon.shot();
}
}
public class PolymorphismClass {
public static void main(String[] args) {
Player player = new Player();
player.firstWeapon = new M4();
player.secondWeapon = new Ak47();
player.attack();
}
}
반면, 위 소스코드처럼 Weapon 이라는 클래스를 선언하여 모든 총이 해당 클래스를 상속받도록 하고, shot 메소드를 Overriding 한다면 Player 클래스의 필드 타입을 Weapon으로 고정하면서도 여러가지 실행 결과를 도출할 수 있게 된다. 이는 필드의 다형성으로 인해 가능한 것이고, 효율성을 높일 수 있다.
[ 3 - 2 ] 매개변수의 다형성
Java는 부모 클래스 타입의 참조변수가 자식 클래스의 인스턴스를 참조하는 것을 허용한다. 마찬가지로 매개변수 타입이 클래스일 경우, 해당 클래스의 인스턴스 뿐만 아니라 자식 클래스의 인스턴스까지 인자로 받을 수 있다.
만약, 운전자가 버스, 택시 등 다양한 자동차를 운행한다고 가정하자. 그렇다면 다음과 같은 소스코드를 작성할 수 있을 것이다.
class Taxi {
void run() {
...
}
}
class Bus {
void run() {
...
}
}
class Driver {
void drive(Taxi taxi) {
taxi.run();
}
void drive(Bus bus) {
bus.run();
}
}
위 코드의 단점은 운전자가 운행하는 자동차의 종류가 많아질수록 새로운 drive 메소드를 추가해야 한다는 것이다. 이를 해결하기 위해 우리는 매개변수의 다형성을 활용할 수 있다.
class Vehicle {
void run() {
}
}
class Taxi extends Vehicle {
void run() {
System.out.println("택시 운행중");
}
}
class Bus extends Vehicle {
void run() {
System.out.println("버스 운행중");
}
}
class Driver {
void drive(Vehicle vehicle) {
vehicle.run();
}
}
public class PolymorphismClass2 {
public static void main(String[] args) {
Driver driver = new Driver();
driver.drive(new Taxi());
driver.drive(new Bus());
}
}
Vehicle 이라는 클래스를 선언하여 모든 자동차 클래스가 해당 클래스를 상속받도록 하고, run 메소드를 Overriding 한다면 Driver 클래스 내부 driver 메소드의 매개변수 타입을 Vehicle로 고정하면서도 여러가지 실행 결과를 도출할 수 있게 된다. 이는 매개변수의 다형성으로 인해 가능한 것이고, 효율성을 높일 수 있다.
[ 4 ] 인터페이스의 다형성
인터페이스의 다형성은 클래스의 다형성과 유사하다. 이 내용은 이전에 업로드 한 인터페이스 글의 스타크래프트 예제에서 repair() 메소드를 확인해주길 바란다.
본문에는 오개념이 있을 수 있습니다. 오개념이 있다면 댓글로 꼭 알려주시길 바랍니다!
아래의 참고자료에 더 많은 내용이 포함되어 있습니다.
[ 참고자료 ]
http://www.tcpschool.com/java/java_polymorphism_concept
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
05-08 다형성
객체지향 프로그래밍의 특징 중에는 **다형성**(폴리모피즘, Polymorphism)이 있다. 도대체 다형성은 무엇이고 이게 왜 필요한 걸까? 예제를 통해 차근차근 알아보자 ...
wikidocs.net
[JAVA] 다형성 -1. 상속에서의 타입변환과 다형성
다형성 (Polymorphism) 하나의 타입에 실행결과가 다양한 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다. 자바에서는 상속, 인터페이스를 이용해 다형성을 구현할 수 있다. 상속
luvyoon.tistory.com
https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
Polymorphism (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated
docs.oracle.com
https://www.w3schools.com/java/java_polymorphism.asp
Java Polymorphism
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
www.w3schools.com
https://www.youtube.com/watch?v=WijVClKt5Z8
'Programming > Java' 카테고리의 다른 글
[Java] Object 클래스 (0) | 2022.08.25 |
---|---|
[Java] 타입 변환 (type conversion) - 자동 타입 변환, 강제 타입 변환 (0) | 2022.08.18 |
[Java] 추상 클래스(abstract class)와 인터페이스(interface) (1) | 2022.08.11 |
[Java] 패키지(Package) (0) | 2022.08.05 |
[Java] Overriding, Overloading (0) | 2022.08.04 |