객체지향 특징에는 4대 개념이 존재한다
- 상속성
- 다형성
- 캡슐화
- 추상화
이중 나는 가장 속을 썩이는 개념이 무엇이냐라고 한다면 다형성(Polymorphism)이라고 생각한다
더군다나 한참 Java + 객체지향에 다가가려 할 때 Design Pattern을 접하게 되면서 더욱더 거리가 멀어지는 것만 같다
내가 다가가기(친해지기) 어려웠던 Interface + 다형성 에 대하여 내가 직접 예제를 작성해 보고 공유하고자 한다.
◼︎ 다형성(Polymorphism) 란? : " 참조 타입에 맞춰서 변한다. " ( 길게 말하지말죠.. 위키피디아 링크 )
◼︎ Interface 란? : 객체를 생성하지 못하는 Java의 추상화 클래스(?) + 상속 자식 클래스는 부모 메서드 필수 오버라이딩, 구현 필요
Interface 키워드를 배울 때 가장 눈에 뜨였던 건 " 변경, 교체에 용이하다. " 이라는 문구였고 그러면서 머리에 떠오른 건
1. 아? 무조건 오버라이딩을 하니까 자식을 한 200개 만들어서 때에 맞춰 자식 생성자를 만들면 변경 교체에 용이하다는 건가???
2. 이건 상속화에도 똑같이 적용되는 거 아닌가?? 뭐가 문제인 거야?? 왜 멋지게 이름 따로 붙여준 거지..? 다중상속 때문에??
패턴공부하면서 가장 충격적(혼자서)이었었던 부분에 대하여 혼자 예제를 만들어보고 공부하였던 부분을 공유하고자 한다
도식화
코드
public interface Sky {
void Watching(int count, String name);
String getOceanName();
}
public class BlueSky implements Sky {
@Override
public void Watching(int count, String name) {
System.out.println(name + " 에는 " + getOceanName()+" 을 보려고 " + count + " 명의 사람들이 바닷가를 찾았습니다.");
}
@Override
public String getOceanName() {
return "파란 하늘";
}
}
public class RedSky implements Sky {
@Override
public void Watching(int count, String name) {
System.out.println(name + " 에는 " + getOceanName()+" 을 보려고 " + count + " 명의 사람들이 바닷가를 찾았습니다.");
}
@Override
public String getOceanName() {
return "파란 하늘";
}
}
public class Ocean {
Sky newSky; // 포함 관계
public void showSky(Sky sky){ // Interface Sky를 매개변수로 받는다.
if (sky instanceof BlueSky) // sky가 BlueSky일땐 강릉으로
sky.Watching(10, "강릉");
else if(sky instanceof RedSky) // sky가 RedSky일땐 목포로
sky.Watching(100, "목포");
return;
}
public void changeOcean(){
newSky = new BlueSky();
newSky.Watching(10000, "뉴욕앞바다");
}
}
public class User {
public static void main(String[] args) {
// 다형성을 활용한 다양한 하늘 호출해보기
Ocean ocean = new Ocean();
ocean.showSky(new BlueSky());
ocean.showSky(new RedSky());
// 다형성을 활용한 바다 위치 바꾸기
ocean.changeOcean();
//ocean.newSky.Watching(10,"ddd"); // 오류가난다
}
}
/* CONSOLE OUTPUT
강릉 에는 파란 하늘 을 보려고 10 명의 사람들이 바닷가를 찾았습니다.
목포 에는 파란 하늘 을 보려고 100 명의 사람들이 바닷가를 찾았습니다.
뉴욕앞바다 에는 파란 하늘 을 보려고 10000 명의 사람들이 바닷가를 찾았습니다.
*/
나만의 충격포인트 1. 인터페이스 참조변수만으로도 메서드를 호출할 수 있단 말이야??
" Sky new = new RedSky() "를 통해서 main 메서드에 운영을 하는 것은 많이들 예제에서 나오는 부분이다
하지만 객체를 생성하지도 않았는데 메서드를 호출해서 틀을 만든다는 것은 직접 예제를 만들어보지 않고서는 느끼지 못하는 부분이었다
Ocean 클래스에서 Sky 타입을 가진 sky 변수로 메서드를 호출, 그리고 구현 객체를 가지고 메서드를 호출한다.
Ocean 클래스에서 개별 Sky를 모두 만들어줄 것인가?
결국 각 Sky에 대한 매써드 호출 하는 것이 아닌 하나의 참조변수로 각각의 메서드를 호출한다는 것
나도 다형성으로 한 발걸음은 다가선 게 아닐까..???
나만의 충격포인트 2. 포함 관계
흔히들 " 상속 " 으로 구현을 하는 것보다는 " 포함 " 관계로 작성을 하는 것이 운영에 도움이 된다고들 한다
근데 왜? 저렇게 해야 할까 라는 생각을 하게 되었는데 막상 예제를 만들어 보려고 하니 각각의 구현된 Sky 메서드들을 호출하려고 하니
포함관계 말고는 생각이 나지 않았다, 또한 상속관계로 구현을 하게된다면 Moon, Sun 과 같은 클래스를 추가한다고 했을때 얼마나 어려울지 다시한번 생각해 볼 수 있었다.
추후 BlackSky 클래스를 구현할지라도 Ocean클래스는 단순히
showSky에서 BlackSky 구현 부분만 추가해 주면 Ocean은 지속해서 사람들이 찾을 것이다
만약 다형성이 없었다면..?
Sky 별로 (RedSky, BlueSky) 오버로딩으로 메서드를 만들 생각을 하니 벌써 머리가 지끈지끈하다.
결론
1. Interface + 다형성 은 불편하게 만들고자 쓰이는것이 아니다 (하지만 남발하는건 디버깅에 불편)
2. 다양한 다형성 운영방법이 있으니 자신만의 예제를 만들어 복습 필요
3. 충격 좀 그만 받아도 될 것 같다.
'개발 > Java' 카테고리의 다른 글
Stream API를 활용해보자 (0) | 2025.01.08 |
---|---|
[JAVA] DI 예제 구현 그리고 UML (0) | 2024.12.29 |
[IDE - IntelliJ] auto Parameter Info (매개변수 정보) 팝업 숨기기 (0) | 2024.11.24 |
자바의 정석 정리 Ver 1.0 (나만 알아볼수 있음) (0) | 2024.10.28 |
프로그램, 객체, 클래스, 메서드 (0) | 2024.10.07 |