다형성 사전적 의미를 보면...
다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다. 자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다.
역시 사전이 하는 소리는 한번에 이해하기가 힘들다.
다형성 말만 보면 다는 다수에다가...음... 형은 형태인것 같은데....? 성은.... 잘 모르겠네... 아마 견디는건가...견딜성?
그렇다 다양한 형태가 다형성이다 뭐 어렵게 생각할것 없다.
우리가 추상화를 배울때 부모는 이름만 만들고(선언부) 기능은 자식이 싹다 만드는(구현부) 형태인것을 확인해 봤다.
그리고 인스턴스화를 시키는 법도 잘 알것이다. 예시) child c1 = new child();
그런데 이번에는 부모가 자식이 만들어 놓은것을 가져오는 일을 할것이다. 예시) parents c1 = new child();
설명하기전에 다형성의 장점을 기억하면서 코드를 보자.
1)코드의 중복을 줄여버림.
2)맴버의 수 조절해서 사용의 제한을 걸어버림.
이젠 코드로 한번 알아보자.
abstract public class cooking {
abstract void stirfrying();
abstract void frying();
abstract void roasting();
}
class koreancuisine extends cooking implements Foodkcal{
void stirfrying(){
System.out.println("한국볶음");
}
void frying(){
System.out.println("한국튀김");
}
void roasting(){
System.out.println("한국굽기");
}
public void Kcalave(){
System.out.println("한국 평균 500kcal");
}
}
class japanesecuisine extends cooking implements Foodkcal{
void stirfrying(){
System.out.println("일본볶음");
}
void frying(){
System.out.println("일본튀김");
}
void roasting(){
System.out.println("일본굽기");
}
public void Kcalave(){
System.out.println("일본 평균 600kcal");
}
}
public interface Foodkcal {
public void Kcalave();
}
public class Main {
public static void main(String[] args) {
cooking ko = new koreancuisine();
ko.frying();
ko.roasting();
ko.stirfrying();
//ko.Kcalave(); 자식에서 추가 한거라 못가져온다.
Foodkcal cal = new koreancuisine();
cal.Kcalave();
cooking jp = new japanesecuisine();
jp.frying();
jp.roasting();
jp.stirfrying();
//jp.Kcalave(); 여기도 자식에서 추가 한거라 못가져온다.
Foodkcal cal2 = new japanesecuisine();
cal2.Kcalave();
System.out.println("--가독성용 경계선--");
//혹은
cooking[] fd = new cooking[]{
ko,jp
};
for(int i = 0; i< fd.length;i++){
fd[i].frying();
fd[i].roasting();
fd[i].stirfrying();
if(fd[i] instanceof koreancuisine){
koreancuisine kcal = (koreancuisine) fd[i];
kcal.Kcalave();
}
else if (fd[i] instanceof japanesecuisine){
japanesecuisine kcal = (japanesecuisine) fd[i];
kcal.Kcalave();
}
}
}
}
출력 결과는 다음과 같다.
한국튀김
한국굽기
한국볶음
한국 평균 500kcal
일본튀김
일본굽기
일본볶음
일본 평균 600kcal
--가독성용 경계선-- (이건 무시하자)
한국튀김
한국굽기
한국볶음
한국 평균 500kcal
일본튀김
일본굽기
일본볶음
일본 평균 600kcal
앞서 말한 장점 두개를 설명하겠다.
1)코드의 중복을 줄여버림.
cooking[] fd = new cooking[]{
ko,jp
};
for(int i = 0; i< fd.length;i++){
fd[i].frying();
fd[i].roasting();
fd[i].stirfrying();
우선 여기만 봐도 부모쪽으로 배열 만들고 묶어서 한방에 처리해 버렸다. 위에 코드랑 비교하면 길이가 줄어드는것을 확인할수 있을것이다.(예제는 자식클래스가 두개지만 자식이 백개 있다고 가정해 보자) 이게 다형성의 최대 장점이다.
그렇다 우리는 비슷한 코드가 쓰이는것을 도저히 참을수가 없다. 그래서 다형성을 써주는 것이다.
그런데 이렇게 하면 자식에서 추가된 kcal를 못쓴다? 우선 밑에 instanceof는 또 뭘까?
if(fd[i] instanceof koreancuisine){
koreancuisine kcal = (koreancuisine) fd[i];
kcal.Kcalave();
}
else if (fd[i] instanceof japanesecuisine){
japanesecuisine kcal = (japanesecuisine) fd[i];
kcal.Kcalave();
}
}
진짜 어렵게 생각하지말자.
instance 가 경우 라는 뜻이 있다는건 알것이다.
At the instance of the backend programmer, they have to know Java! (백엔드 프로그래머인 경우 자바를 알아야 한다!)
그런데 이게 아니다.
if(fd[i] instanceof koreancuisine)
자바식으로 해석하면...
fd라는 참조변수가 instanceof(어떤 객체를 참조하고 있는데) 그 참조를 koreancuisine으로 부터 온것이냐 true false.
이말이다. 더는 설명이 필요 없을 것 같다.
여기 까지 읽으면 의문이 들것이다. 아니 왜 사서 고생함? 그냥 자식이 싹다 선언해서 다 써버리면 되지. 좀 까다로워도 자식도 배열로 하나하나 만들지 뭐! 라는 생각을 가지는 것이 지극히 정상이다.
그런데 앞서 말했듯 자식이나 메서드가 백개가 넘는다고 생각해보자. 그런데 매번 자식을 전부 불러오면 필요없는 기능까지 가져올수 있는 것이다.
예를들어 우리가 라면을 먹는다고 생각해보자 식기통에는 젓가락도 있고 수저도 있고 포크도 있고 나이프도 있고 주걱도 있고 뒤집게도 있고 국자도 있고... 등등등 많다고 가정해보자.
라면 먹을때 다 꺼내서 먹을것인가? 아니다 젓가락 혹은 수저까지만 필요할 것이다.(포크로 드시는분은 죄송합니다...그저 비유가...)
여기서 두번째 장점이 나오는것이다
2)맴버의 수 조절해서 사용의 제한을 걸어버림..
불필요한 요소를 제한해서 가독성을 높히는데 한몫을 한다. 필요한 기능만 쏙쏙 뽑아서 쓰는것이지.
그래서
cooking ko = new koreancuisine();
ko.frying();
ko.roasting();
ko.stirfrying();
//ko.Kcalave(); 자식에서 추가 한거라 못가져온다.
부모가 자식껄 가져오게 될때는 자식이 직접 만든 메서드는 가져오지 못하게 된다.
'자바 > 정리' 카테고리의 다른 글
(JAVA) Object 클래스 equals() (0) | 2022.12.08 |
---|---|
(JAVA) 예외 (1) | 2022.11.30 |
(JAVA)인터페이스 (0) | 2022.11.21 |
(JAVA) 추상화 (0) | 2022.11.17 |
(JAVA)캡슐화 (getter와 setter) (0) | 2022.11.13 |