자바를 배우는 우리에게 OOP란 정말 중요한 개념이다. 그 중에서도 다형성이라는 부분이 언뜻보기엔 쉬워보이면서도 막상 보면 그렇지 않다. 이번 시간을 통해 다형성에 대해서 좀 더 자세하게 알아보도록 하자.
다형성(Polymorphism)이란 무엇일까?
다형성은 이름 그대로 어떤 객체의 속성이나 기능이 상황에 따라 여러 형태를 가질 수 있다는 개념이다. 현실에 빗대어 비유하자면, 나라는 존재는 누군가의 자식이 될 수도, 누군가의 친구가 될 수도, 누군가의 아버지가 될 수도 있는 상황과 맥락에 따라 달라지는 것과 비슷하다고 할 수 있다.
이를 프로그래밍에 대입하면, 다형성이란 같은 자료형에 여러가지 타입의 데이터를 대입하여 다양한 결과를 얻어낼 수 있는 성질을 의미한다.
자바에선 대표적으로 Overloading, Overriding, Upcasting, Downcasting, Interface, Abstract 방법이 모두 다형성에 속한다고 생각하면 된다.
즉, 다형성은 클래스가 상속 관계에 있을때 나타나는 다채로운 성질인 것.
🟩중요!
객체지향 프로그래밍에서 다형성이란 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것을 의미한다. 좀 더 구체적으로는, 상위 클래스 타입의 참조 변수로 하위 클래스의 객체를 참조할 수 있도록 하는 것이다.
코드를 통해 보도록 하자.
public interface Login {
String name = "인터페이스";
void login();
}
---------------------------------------------------------------
public class Naver implements Login {
String name = "네이버";
@Override
public void login() {
System.out.println("네이버에 로그인 합니다.");
}
public void naverSports() {
System.out.println("네이버 스포츠에 접속합니다.");
}
}
---------------------------------------------------------------
public class Kakao implements Login {
String name = "카카오";
@Override
public void login() {
System.out.println("카카오에 로그인 합니다.");
}
public void kakaoTalk() {
System.out.println("카카오톡을 이용합니다.");
}
}
위와 같이 Login 인터페이스를 구현한 Naver 클래스와 Kakao 클래스를 정의하고
public class User {
@Override
void login(Naver naver) {
naver.login();
}
@Override
void login(Kakao kakao) {
kakao.login();
}
}
Naver와 Kakao에 접속하는 User 클래스를 정의했다.
이제 User 클래스는 loginN과 loginK 메서드를 통해 각각 Naver와 Kakao에 로그인을 할 수 있다. 그런데 만약 로그인 하려는 도메인의 개수가 1,000개라면 1,000개의 도메인에 접속하는 모든 메서드를 구현해야 하는 문제를 맞딱드리게 될 것이다.
우리는 이를 다형성을 통해 정말 간단하게 해결이 가능한데,
public class User {
void loginDomain(Login domain) {
domain.login();
}
}
바로 이와 같이 매개변수로 각 도메인들이 구현한 인터페이스 타입을 참조변수로 전달해주기만 하면 되는 것이다. 물론, 모든 도메인이 Login 인터페이스를 구현했다는 가정에서만 작동한다 ㅎㅎ.
이를 활용하면 여러 종류의 서로 다른 객체를 하나의 배열로 다루는 일이 가능해진다.
public class Main {
public static void main(String[] args) {
Login[] logins = new Login[2];
logins[0] = new Naver();
logins[1] = new Kakao();
}
대신 이와 같이 상위 타입으로 선언하여 배열에 담은 후 다시 꺼내어 해당 객체를 사용하고 싶은 경우에 주의해야 할 점이 있다.
- 하위 타입의 메서드 사용 불가
타입의 선언을 Login(상위 타입)으로 했기 때문에 logins[0].naverSports 와 같은 동작은 불가능하다. 당연히 @Override 한 login 메서드는 정상 작동한다.
하위 타입의 메서드를 사용하고 싶은 경우에는 다시 다운캐스팅을 해주어 사용하면 된다.
위와 비슷한 또 다른 예제를 살펴보자.
이번 예제는 우리도 모르게 다형성을 계속해서 이용해왔음을 알려주는 예제이다.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
바로 String 의 equals()메서드 이다. 위 메서드는 파라미터로 Object 를 전달받고 있다. 모든 객체의 최상위 타입이기 때문에 이도 상속에 포함되며 다형성에 포함된다고 볼 수 있다. if (anObject instanceof String).. 부분을 통해 anObject 객체가 String 클래스인지 확인을 하고, 그것이 맞다면 String으로 다운캐스팅 한 후에 비교를 하고 있음을 볼 수 있다.
이처럼 다형성을 활용하면 하나의 타입만으로 여러 가지 타입의 객체를 참조할 수 있어 보다 간편하고 유연하게 코드를 작성하는 것이 가능해진다.
Reference
https://www.codestates.com/blog/content/객체-지향-프로그래밍-특징
https://inpa.tistory.com/entry/OOP-JAVA의-다형성Polymorphism-완벽-이해
'Java' 카테고리의 다른 글
가상 스레드 (Virtual Thread) 에 대하여 - (1) (0) | 2024.09.05 |
---|
자바를 배우는 우리에게 OOP란 정말 중요한 개념이다. 그 중에서도 다형성이라는 부분이 언뜻보기엔 쉬워보이면서도 막상 보면 그렇지 않다. 이번 시간을 통해 다형성에 대해서 좀 더 자세하게 알아보도록 하자.
다형성(Polymorphism)이란 무엇일까?
다형성은 이름 그대로 어떤 객체의 속성이나 기능이 상황에 따라 여러 형태를 가질 수 있다는 개념이다. 현실에 빗대어 비유하자면, 나라는 존재는 누군가의 자식이 될 수도, 누군가의 친구가 될 수도, 누군가의 아버지가 될 수도 있는 상황과 맥락에 따라 달라지는 것과 비슷하다고 할 수 있다.
이를 프로그래밍에 대입하면, 다형성이란 같은 자료형에 여러가지 타입의 데이터를 대입하여 다양한 결과를 얻어낼 수 있는 성질을 의미한다.
자바에선 대표적으로 Overloading, Overriding, Upcasting, Downcasting, Interface, Abstract 방법이 모두 다형성에 속한다고 생각하면 된다.
즉, 다형성은 클래스가 상속 관계에 있을때 나타나는 다채로운 성질인 것.
🟩중요!
객체지향 프로그래밍에서 다형성이란 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것을 의미한다. 좀 더 구체적으로는, 상위 클래스 타입의 참조 변수로 하위 클래스의 객체를 참조할 수 있도록 하는 것이다.
코드를 통해 보도록 하자.
public interface Login {
String name = "인터페이스";
void login();
}
---------------------------------------------------------------
public class Naver implements Login {
String name = "네이버";
@Override
public void login() {
System.out.println("네이버에 로그인 합니다.");
}
public void naverSports() {
System.out.println("네이버 스포츠에 접속합니다.");
}
}
---------------------------------------------------------------
public class Kakao implements Login {
String name = "카카오";
@Override
public void login() {
System.out.println("카카오에 로그인 합니다.");
}
public void kakaoTalk() {
System.out.println("카카오톡을 이용합니다.");
}
}
위와 같이 Login 인터페이스를 구현한 Naver 클래스와 Kakao 클래스를 정의하고
public class User {
@Override
void login(Naver naver) {
naver.login();
}
@Override
void login(Kakao kakao) {
kakao.login();
}
}
Naver와 Kakao에 접속하는 User 클래스를 정의했다.
이제 User 클래스는 loginN과 loginK 메서드를 통해 각각 Naver와 Kakao에 로그인을 할 수 있다. 그런데 만약 로그인 하려는 도메인의 개수가 1,000개라면 1,000개의 도메인에 접속하는 모든 메서드를 구현해야 하는 문제를 맞딱드리게 될 것이다.
우리는 이를 다형성을 통해 정말 간단하게 해결이 가능한데,
public class User {
void loginDomain(Login domain) {
domain.login();
}
}
바로 이와 같이 매개변수로 각 도메인들이 구현한 인터페이스 타입을 참조변수로 전달해주기만 하면 되는 것이다. 물론, 모든 도메인이 Login 인터페이스를 구현했다는 가정에서만 작동한다 ㅎㅎ.
이를 활용하면 여러 종류의 서로 다른 객체를 하나의 배열로 다루는 일이 가능해진다.
public class Main {
public static void main(String[] args) {
Login[] logins = new Login[2];
logins[0] = new Naver();
logins[1] = new Kakao();
}
대신 이와 같이 상위 타입으로 선언하여 배열에 담은 후 다시 꺼내어 해당 객체를 사용하고 싶은 경우에 주의해야 할 점이 있다.
- 하위 타입의 메서드 사용 불가
타입의 선언을 Login(상위 타입)으로 했기 때문에 logins[0].naverSports 와 같은 동작은 불가능하다. 당연히 @Override 한 login 메서드는 정상 작동한다.
하위 타입의 메서드를 사용하고 싶은 경우에는 다시 다운캐스팅을 해주어 사용하면 된다.
위와 비슷한 또 다른 예제를 살펴보자.
이번 예제는 우리도 모르게 다형성을 계속해서 이용해왔음을 알려주는 예제이다.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
바로 String 의 equals()메서드 이다. 위 메서드는 파라미터로 Object 를 전달받고 있다. 모든 객체의 최상위 타입이기 때문에 이도 상속에 포함되며 다형성에 포함된다고 볼 수 있다. if (anObject instanceof String).. 부분을 통해 anObject 객체가 String 클래스인지 확인을 하고, 그것이 맞다면 String으로 다운캐스팅 한 후에 비교를 하고 있음을 볼 수 있다.
이처럼 다형성을 활용하면 하나의 타입만으로 여러 가지 타입의 객체를 참조할 수 있어 보다 간편하고 유연하게 코드를 작성하는 것이 가능해진다.
Reference
https://www.codestates.com/blog/content/객체-지향-프로그래밍-특징
https://inpa.tistory.com/entry/OOP-JAVA의-다형성Polymorphism-완벽-이해
'Java' 카테고리의 다른 글
가상 스레드 (Virtual Thread) 에 대하여 - (1) (0) | 2024.09.05 |
---|