최 윤 정 Dept. of Computer Science&Engineering

Slides:



Advertisements
Similar presentations
3. 메소드와 변수 SCJP 자격증 프로젝트 발표자 : 최선웅. 1. 메 소 드 개 념 2. 메 소 드 양 식 3. 메 소 드 변 수 4. 메 소 드 예 제 5. 참 고 문 헌 / 자 료 목 차.
Advertisements

01_ 가상 함수를 사용한 다형성의 구현 02_ 오버라이딩
클래스 class, 객체 object 생성자 constructor 접근 access 제어 이벤트 event 처리.
Chap07 상속 Section 1 : 상속의 개요 Section 2 : 멤버 변수의 상속
최윤정 Java 프로그래밍 클래스 상속 최윤정
Ch.07-5 xml-rpc 사용하기 김상엽.
Java로 배우는 디자인패턴 입문 Chapter 5. Singleton 단 하나의 인스턴스
JAVA 언어로 배우는 디자인 패턴 입문 chap. 1-2.
Windows Server 장. 사고를 대비한 데이터 백업.
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
8.1 인터페이스 개요와 인터페이스 정의 8.2 인터페이스의 사용 8.3 인터페이스의 상속 8.4 인터페이스 참조
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
8장. 심각한 다형성 “추상”과 “구상”의 차이점에 대해 알아봅니다. Object 클래스에 대해 알아봅니다.
어서와 Java는 처음이지! 제7장 상속.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
자바 5.0 프로그래밍.
패키지와 접근 제어 패키지에 대하여 접근 제어에 대하여.
학습목표 학습목차 다른 홈페이지의 HTML 파일 코드를 보는 방법에 대해 알아봅니다.
자료구조: CHAP 4 리스트 (3) 순천향대학교 컴퓨터공학과 하 상 호.
10장. 예외처리.
자바 5.0 프로그래밍.
10강. JSP 본격적으로 살펴보기-II 스크립트릿, 선언, 표현식 지시자 주석 Lecturer Kim Myoung-Ho
7장 인터페이스와 추상 클래스.
Method & library.
자바 5.0 프로그래밍.
자바응용.
박성진 컴퓨터 프로그래밍 기초 [09] 배열 part 1 박성진
29강 JAVA 스레드 - 스레드란? - 멀티스레드 문법 - synchronized Lecturer Kim Myoung-Ho
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
Lesson 2. 기본 데이터형.
Lab 1 Guide: 교재 2장 DrawX ( 쪽)
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
Effective Java [Issue 1 and 2]
27강 JAVA Collections - II - Map계열 컬렉션 클래스 살펴보기 - Set계열 컬렉션 클래스 살펴보기
15장 컬렉션 프레임워크 Section 1 컬렉션 프레임워크의 개요 Section 2 리스트 Section 3 셋
3D 프린팅 프로그래밍 01 – 기본 명령어 강사: 김영준 목원대학교 겸임교수.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
6강. 객체지향 프로그램의 시작 객체지향 이전의 프로그래밍 객체지향의 등장 배경과 이해 메소드의 이해
20장. 객체지향 프로그래밍 01_ 객체지향 프로그래밍의 시작.
Part 4 클래스 라이브러리 Chapter 10 : 다중 스레드 Chapter 11 : 패키지와 주요 클래스
자바 5.0 프로그래밍.
Power Java 제11장 상속.
5강. 배열 배열이란? 배열의 문법 변수와 같이 이해하는 배열의 메모리 구조의 이해 레퍼런스의 이해 다차원 배열
20강 패턴을 통한 객체지향 언어의 이해 - II - 난이도 있는 패턴 예제 - I Lecturer Kim Myoung-Ho
9강. 클래스 실전 학사 관리 프로그램 만들기 프로그래밍이란 결국 데이터를 효율적으로 관리하기 위한 공구
15강. 폼 데이터 값 검증 Validator를 이용한 검증 ValidationUtils 클래스
JA A V W. 06.
14강. 세션 세션이란? 세션 문법 Lecturer Kim Myoung-Ho Nickname 블스
10장 상속 Section 1 상속의 개요 Section 2 상속과 한정자 Section 3 상속과 생성자
12. 상속 : 고급.
객체기반 SW설계 팀활동지 4.
18강. 인터페이스 – II - 인터페이스와 다중상속 - 인터페이스를 통한 로봇 장남감 만들기 프로그래밍
( Windows Service Application Debugging )
바넘효과 [Barnum effect] 사람들이 보편적으로 가지고 있는 성격이나 심리적 특징을 자신만의 특성으로 여기는 심리적 경향. 19세기 말 곡예단에서 사람들의 성격과 특징 등을 알아 내는 일을 하던 바넘(P.T. Barnum)에서 유래하였다. 1940년대 말 심리학자인.
클래스 : 기능 CHAPTER 7 Section 1 생성자(Constructor)
중복 멤버의 처리 조 병 규 한 국 교 통 대 학 교 SQ Lab..
가장 많이 사용 Accelerator 최상위 WM_COMMAND, OLE 메시지 관련 이벤트 처리만 가능 이 클래스를 상속받아서 다른 이벤트 처리 이벤트 처리 관련 윈도우(창) 최상위 클래스 멀티 테스킹(모듈) CFrameWnd, Cview,
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
여러 가지 집의 같은 점과 다른 점 비교하기 슬기로운 생활 2학년 1학기
안드로이드 앱 개발과정 Step1. 기초과정 강사 : 정 훈 희.
함수, 모듈.
9 브라우저 객체 모델.
Android -Data Base 윤수진 GyeongSang Univ. IT 1.
2.가상머신의 탐험 도구, Oolong에 대하여 ps lab 김윤경.
워드프로세서 스프레드시트 문서 관리 인터넷 활용
자바 객체 지향 프로그래밍 Ps lab 김윤경.
7 생성자 함수.
6 객체.
BoardGame 보드게임 따라가기.
Presentation transcript:

최 윤 정 cris@konkuk.ac.kr Dept. of Computer Science&Engineering 컴퓨터 응용 및 실습 Part1. OOP&Java Programming Class, Interface-Review 합성구조-Battle Item 최 윤 정 cris@konkuk.ac.kr Dept. of Computer Science&Engineering

지난 시간 review 및 feedback 지난 시간 review & 어려웠거나 이해가 힘든 부분 질문 사탕줄께요

다중 상속의 문제점 DigitalRecorder 자바에서는 다중 상속을 허용하지 않습니다. CDBurner DVDBurner int i burn() 자바에서는 다중 상속을 허용하지 않습니다. CDBurner int x burn() DVDBurner int x burn() ComboBurner burn(); 누구의 x? burn()!! 누구의 burn()!!

클래스와 인터페이스의 활용 다중 상속 : 여러 개의 클래스에서 상속받는 것 , C++까지는 가능했으나 죽음의 diamond .. 탱크는 자동차일까 대포일까? 자바에서 상속은 단 한번 대포는 기능을 구현. 자동차, 날수있는 자동차와 비행기, 아이언맨, 을 모두 표현할 수 있는 방법은? ‘날수있는’ 기능을 interface로 만들어 구현

다중 상속의 코드 Java에서는 클래스 다중상속을 허용하지 않는 대신, 인터페이스 구현을 통해 의미적으로 구현한다. 또는, 속성의 상속은 클래스로 상속 깊이를 확장하고, 기능은 인터페이스로 너비를 확장한다. class 자동차{ 동작한다() } interface 대포{ 발사한다(); Class tank extends 자동차 implements 대포{ …. //동일

오늘은 클래스 vs. 인터페이스 Lab: Review 상속(inheritance) vs. 합성(composition) 이미 만들어진 동물 클래스 중 애완동물은 어떻게 구현할까? 상속(inheritance) vs. 합성(composition) 동물원 동물과 야생동물 Battle Item 확장성과 유연성을 높이는 방법은? 코드수정을 줄일 수 있는 방법

클래스 상속과 추상클래스, 인터페이스 … 동물 : 애완동물과 야생동물 UML : 클래스다이어그램의 쉬운 설명 동물 : 애완동물과 야생동물 UML : 클래스다이어그램의 쉬운 설명 http://prezi.com/wrc1ylli_adw/copy-of-uml/ http://hongjinhyeon.tistory.com/25

동물 : 야생동물 vs. 애완동물 호랑이,사자,늑대,고양이,강아지를 동물의 하위클래스로 만들어 상속 트리로 구성했습니다. 각 동물마다 기본적인 속성과 동작을 넣어둘 것이고 자연스럽죠? 그런데 가만히 보니 구분하고 싶어집니다. 무서운 야생동물과 귀여운 애완동물. 우선, Dog클래스와 Cat클래스만 애완용으로 만들어 봅니다. Animal Pet -.애완동물(Pet 객체)의 행동인 beFriendly(), play() 같은 메소드가 있어야 합니다. -.그냥 Dog 클래스에 이런 메소드를 바로 추가하면 어떨까요?? -.애완동물 Cat과 Dog의 beFriendly()와 Play() 는 서로 다르게 정의되어야 합니다. Canine Feline Lion Hippo Cat Dog Tiger Wolf

야생동물 vs. 애완동물 : 방법 1 첫 번째 방법 : 최상위 클래스에 넣어 상속되도록 상속을 활용하자. 애완동물의 성질을 나타내기 위한 메소드를 Animal 클래스에 집어넣는다.! 장점 모든 Animal 객체에 애완동물의 행동이 상속되는 단순 구조. 기존의 하위클래스를 전혀 건드리지 않아도 되고 새로 만드는 ‘치와와’ 하위클래스에서도 해당 메소드를 사용할수 있습니다. 단점 호랑이, 사자, 늑대도 애완동물 기능코드가 들어있습니다. wolf.play() 즉, 늑대가 재주를 부릴 수도 있어서.. 애완동물이 아닌 동물에게 애완동물의 행동을 부여하는 것이 적절치 않은데다 공통의 애완동물기능이 상속되며, 각 애완동물마다 행동이 많이 다르기 때문에 일일이 수정해야 한다는 부담이 있습니다. beFriendly(){ …} play(){…} sing(){…}

야생동물 vs. 애완동물 : 방법 2 두 번째 방법 : 추상 클래스/추상메소드 Animal클래스에 beFriendly(), play(),sing()메소드를 추가할 때 추상 메소드로 만들어 하위클래스에서 오버라이드 해야만 쓸 수 있도록 만듭니다. 장점 엉뚱한 클래스에서 엉뚱히 오버라이드만 하지 않으면 Pet용 메소드가 실행되지 않도록 할 수 있습니다 단점 늑대, 사자, 호랑이 등의 하위클래스에서는 비어있는 블럭코드를 무조건 만들어 수정해야합니다. 일부 유형에만 적용할 것을 상위클래스인 Animal 클래스에 집어넣는다는 자체가 잘못된 접근법이라고 할 수 있습니다. Abstract Pet abstract void beFriendly(); abstract void play();

야생동물 vs. 애완동물 : 방법 3 세 번째 방법 : 각각의 하위클래스들을 수정 애완동물용 메소드인 beFriendly(), play(), sing()를 사용할 클래스에만 집어넣습니다.! 예) 사자,호랑이, 늑대는 변경하지 않고, 병아리, 개, 고양이등에만 넣는 것으로 수정합니다. 장점 애완동물이 아닌 야생동물에 애완동물용 메소드가 들어갈 걱정을 하지 않아도 됩니다. Dog나 Cat이 아닌 다른 클래스에서는 전혀 애완동물관련 메소드를 쓸 수 없도록 할 수 있습니다. 단점 제대로 된 계약서를 갖춰야 합니다. 다형성을 적용할 수가 없습니다. Dog가 아닌 새로운 동물에 Pet 기능을 적용할 때마다 수정이 필요합니다.

Interface <<Pet>> 야생동물 vs. 애완동물 : 방법 4 네번째 방법 : 인터페이스 활용 애완동물의 행동 beFriendly(), play(), sing() 들의 메소드를 모아 Pet 인터페이스로 만들고, 각 클래스와 연결하고 애완동물의 기능이 필요한 동물들만 implements 하게 합니다. public class Dog extends Canine implements Pet {…} 장점 모든 애완동물 클래스에 같은 메소드 이름을 가지고 있어 동일 이름으로 메소드를 호출이 가능하므로 다형성을 유지할 수 있습니다. 연결된 하위클래스에서 반드시 구현해야만 하므로 상속받은 것 중에 어떤 것을 호출해야 할지 결정할 수 없게 되는 문제가 생기지 않습니다. <<Pet>>기능이 필요한 다른 상속트리로의 확장도 가능합니다. 청소가능한-로봇, 펫기능이 있는-로봇 등등 단점 … Interface <<Pet>> default void beFriendly(){..} abstract void play();

Pet 인터페이스 정의 및 구현 public interface Pet { public abstract void beFriendly(); public abstract void play(); } public class Dog extends Canine implements Pet { //Overriding public void beFriendly() {//반드시 구현해야함…} public void play() {// 반드시 구현해야함…} public void roam() {//…} public void eat() {//…}

Robot Animal Pet Canine Agent RoboDog Feline Lion Hippo Cat Dog Tiger name Age location … makeNoise() eat() sleep() roam() Robot Animal Pet Canine Agent RoboDog Feline Lion Hippo Cat Dog Tiger Wolf

상속 vs. 구현 vs. 합성 -문법의 차이가 아닌 설계와 활용에 있어서. -만들어야 할 ’객체’(대상)을 이해하는 것 부터 생각합니다. -OOP 구조 및 설계의 원칙 -디자인패턴, 코딩패턴, MVC 모델 등에 대한 문서도 함께 찾아 읽어보도록 하세요.

OOP : 객체는 어떻게 만들어야 할까요? 어떻게 생겼고, 어떤 기능이 있는지 이해해야 합니다. 처음부터 ‘완벽’하게 만들 수는 없기 때문에 시작은 ‘추상’적으로! 점점 파생시키고 확장시켜 나갑니다. 본질은 잃지 말아야 하며, 수정, 관리, 활용, 재사용하기에도 쉬워야 합니다. 거대한 클래스 하나가 아니라, 작고 견고하며, 동적 제어가 가능한, 느슨한 결합구조를 갖는 구조로…

대상(객체)에 대해 ‘이해’해야 하는 이유1 알고 있는 만큼 코드가 얼마나 달라질 지, 예상이 되지요?

지난주 과제 feedback : I am & I have & I like 다들 나는 선생님, 스스로를 학생들로 표현했는데, 문제 ! 여러분은 영원히 학생이 아니라는 점 여러 역할을 하고 있는 점 : 학생이면서 과외선생님..? 내 꿈은? 이루어지지 않았으나 분명 언젠가는 실현될터인데..? 만약 여러분이 student이면서 teacher 이면서 누군가의 friend이면서, 여러분도 friend를 가지고 있다면, 공통적으로 모두 ‘사람’ 이므로, 가장 일반적인 ‘사람’의 형태를 상속받을 수 있으나, 각각의 완전한 subclass를 만들어 주어야 하며, superclass에서 허용한 모든 조작은 subclass에서도 모두 허용해야 합니다. (각 역할들의 combination까지 생각해주면 굉장히 많아지겠죠..--) 게다가 시간에 따라서 역할이 달라지는 경우이므로 Static relationship을 맺고 있는 상속으로는 시간에 따른 변화를 표현하기도 힘들고 동적인 변화를 제어하기가 어렵습니다.

기능과 규약, 역할에 따른 행동을 구분하기

상속과 합성.. 동적 바인딩 클래스 상속(inheritance)과 인터페이스 구현 이제는 편안한 개념이기를 ^^ OOP에서 가장 일반적인 재사용의 수단 상위 클래스의 구현을 하위 클래스가 물려 받아 확장하는 편안하고 쉬운 개념 상위 클래스의 속성과 메소드를 하위클래스가 그대로 재사용 메소드 오버라이딩(method overriding)을 통해 클래스의 기능을 재정의 할 수 있고 하위 클래스 나름의 새로운 메소드를 추가하면서 기능을 확장한다 이제는 편안한 개념이기를 ^^

상속과 합성.. 동적 바인딩 과거 OOP 스타일은 일단 상속을 사용하는 경우가 많았으나, 복잡한 문제&규모가 클 수록 깊은 상속 트리와 그로부터 파생된 클래스들을 관리하고 수정하는 일 그 자체가 부담이 됩니다. 여러 역할을 가진 객체를 표현하고 사용하기에는 애완동물의 단순한 경우에서도 보았듯이 적절치 않습니다. 문제에 따라 기능과 규약, 역할은 세분화될 필요도 있습니다. 그러나 Is-a-kind-of .. Is-a-role-of .. 등은 엄밀히 is-A는 아니어서 상속은 어울리지 않아요. So, 객체의 기능에 대한 제어 효율성과 유연성, 편의성을 부여하기 위해 느슨한 커플링을 유지하고 동적바인딩이 용이하도록 상속은 (물리적인) 속성과 보편적 기능의 확장에만 사용합니다. 구조이해와 유지에 방해되지 않도록 너무 깊은 상속트리는 피하고, 얕은 상속트리 + 합성, 즉, 인터페이스를 갖는 구조로 만드는 것이 유리합니다.

상속과 합성.. 동적 바인딩 합성 : has-a Delegation을 응용한 예 중 하나 Car – engine. Owner – helper. 한 클래스가 다른 객체들을 멤버로 갖는 형태. 자신이 해야 할 작업을 다른 객체에게 위임(delegation)하여 대신 실행하게 하는 용도. 한 클래스에서 다른 클래스의 객체를 변수처럼 이용하고 메시지전달도 가능한 구조로 많은 패턴에서 사용됩니다. "상속"의 남용보다, "합성"을 사용하여 확장하는 것이 더 좋은 객체 지향 설계가 될 수 있어요. 기능 및 규약은 interface, 역할은 ‘합성’을 적용해보세요. (* 디자인 패턴 중 delegation …참고하기 , 읽어보기 : http://khlim76.egloos.com/3902359)

합성구조의 간단한 예 (1/3) class Data{ … } 를 이용해서 class A 가 데이터를 저장하거나 읽어오는 작업을 해야할 때 더욱 느슨한 커플링을 위해 읽기/쓰기 작업에 대한 인터페이스 IData를 선언해 주는 예 class A extends Data { …. public String getMsg() { return ….; } class Data { class A { Data data = new Data(); …. public String getMsg(){ return data.getMsg(); } class A { IData data; …. public A(Idata data){ this.data = data; } public String getMsg(){ return this.data.getMsg(); Interface IData { public String getMsg(); public void setMsg(String m);

합성구조의 간단한 예 (2/3) : Printer RealPrinter는 실제 출력가능한 프린터 Printer는 제어판의 프린터라고 가정해봅니다. //상속구조와의 차이점을 비교해고 //어떻게 구성하는 것이 편한지 생각해보세요 Printer 클래스에 있는 print() method 를 보세요. Print기능을 수행하지만 RealPrinter 의 print에게 위임된 형태로 수행되어, 실제로 수행되는 method 는 RealPrinter 의 print()가 실행되고 있습니다.

합성구조의 예 (3/3) : 동적바인딩에 의한 다형성 합성구조의 예 (3/3) : 동적바인딩에 의한 다형성 상속대신 Delegation을, 그리고 interface 를 사용함으로써, 클래스는 훨씬 더 유연해지게 됩니다. C는 클래스는 - 인터페이스 변수 i 를 이용하여 A 클래스와 B로 생성된 객체의 참조변수를 가질 수 있고 - A와 B의 교환을 위한 메소드가 있어요. - 따라서 Delegation의 교환은 클래스 C의 toA(), toB()를 통해 이뤄집니다. 게다가 동적으로 어떤 객체의 역할이나 기능을 변경할 때에도 쉽게 적용될 수 있어요. 깊은 상속 트리와 다소 복잡한 코드를 가진 경우 interface를 구현할 때 override 해야 하는 문제에서 좀더 자유롭겠지요.. 옆 코드를 그림으로 그려보세요.

상속? 동물원동물 vs. 야생동물 “사자", "호랑이" 등의 하위클래스가 "동물" 클래스를 "상속"하도록. 사자와 호랑이는 본질적으로 동물이기 때문에. 또한 동물은 일단 한번 태어나면 그 동물로 평생을 보낸다. 시간에 따라서 사자가 호랑이로 변하거나 호랑이가 사자로 변하는 일은 일어나지 않는다. 동물원 호랑이가 탈출하면 야생호랑이, 야생호랑이가 잡혀오면 동물원 호랑이가 되는 동작은? "동물" 클래스의 하위 클래스로 "야생 동물", "동물원 동물"을 정의하는 것은 바람직하지 않다. "야생 동물"을 잡아서 동물원에서 키우면 "동물원 동물"이 되는 변경성 있으므로. 합성구조는, 항구적인 "IS A" 관계가 아닌 시간에 따라 변할 수 있는 "역할"을 표현하기에 적합하므로 적용해 봅니다. 상속?

동물원 동물 vs. 야생동물 동물은 동물의 역할을 가지고있다. 동물의 역할로는 야생동물의 역할과 동물원동물의 역할로 구분된다. 예) 야생동물 : 사냥하기(), 동물원 동물: 묘기부리기(); "야생 동물"과 "동물원 동물"은 잡히기 이벤트나, 시간(run-time)에 따라 변할 수 있는 역할이므로. 상속보다는 "합성"을 이용하여 클래스들을 연결해본다. AnimalRole은 "야생 동물"과 "동물원 동물"의 상위 클래스이며, 하위 클래스에서는 각 동물별로 차별화 된 속성값과 메소드의 내부 구현을 포함하면 된다.

동물원 동물 vs. 야생동물 : 이런 방법도 있고

동물원 동물 vs. 야생동물 : 이런 방법도 있어요 먼저 스스로 만들어 보고 수업게시판을 참고하세요 다른 클래스들도 추가해보세요. GUI를 공부하는 학생들은 숲속마을화면/동물농장 화면을 만들고 윈도우에서 동작되도록 만들어봅니다.

Battle Item : 무기-방어구-신발 Go !!

Item : 상속관계로 구현한 클래스(1/3) 기본적으로, 아이템이라는 클래스를 생성하고 하위 클래스로 무기, 방어구, 신발을 생성한다. 자연스럽게. 무기는 아이템이다. 방어구는 아이템이다. 신발은 아이템이다. 아이템들의 아이디는 String이다. Armor . printfInfo(Object mgs); Weapon Boots Item String ID; getID();

Item : 상속관계로 구현한 클래스(2/3) *Super class인 Item에서 ID는 public abstract class Item { private String ID; public Item(String ID) { this.ID = ID; } public String getID() { return ID; abstract void printInfo(Object msg); *Super class인 Item에서 ID는 private String ID; 로 정의되었음 public class Weapon extends Item { public Weapon(String ID) { super(ID); } public void printInfo(Object msg) { System.out.println("--- 무기 ---"); System.out.println(msg.toString()); System.out.println("-----------------"); Wepon.java public class Boots extends Item { public Boots(String ID) { super(ID); } @Override public void printInfo(Object msg) { System.out.println("--- 신발 ---"); System.out.println(msg.toString()); System.out.println("-----------------"); Boots.java public class Armor extends Item { public Armor(String ID) { super(ID); } @Override public void printInfo(Object msg) { System.out.println("--- 방어구 ---"); System.out.println(msg.toString()); System.out.println("-----------------"); Armor.java

Item : 상속관계로 구현한 클래스(3/3) public class ItemExample { public static void main(String[] args) { Item[] items = new Item[3]; items[0] = new Weapon("매직 롱 스워드"); items[1] = new Armor("드래곤 메일"); items[2] = new Boots("아마존 부츠"); //제어코드 예 for(int i = 0; i < items.length; i++) { if(items[i].getID().compareTo("매직 롱 스워드")==0) { System.out.println("롱 스워드에 마법을 부여 하였습니다.\n"); } printItemInfo(items[i]); } }     private static void printItemInfo(Item item) {         System.out.println("이 아이템의 ID는 " + item.getID() + "입니다.");         item.printInfo("아이템 정보");         System.out.println(“ ");     } } 위기상황! 모든 구현이 끝났는데 변경사항이 생겼다. 모든 무기들은 Item을 상속받아 만들어졌는데, Item 필드의 형태를 변경해야 한단다. 현재, 최상위 클래스에서 아이디는 모두 String.. 그러나, 아이템들의 종류와 개수가 늘어나면서 문자형 이름이 아닌 정수형 코드로 관리되도록..ㅜ 부모 클래스에서 아이디를 숫자로 변경한다면, 수정해야 할 부분과 영역이 …. 많다 …!!

가능한 처리 방법은? 상속관계를 끊어버리고 처음부터 뒤엎고 다시.!? 현재상태를 유지하기 위해 쫒아다니면서 가능한 모든 것을 수정.!? 설계를 조금 수정하더라도 앞으로 올 더 큰 변경에 대해 대비?! 시작할 때 부터, 느슨한 구조로 , 변경이 쉽게, 좋은 패턴을 적용해서 만들어보자.! 최소한의 변경을 위해 Item과 무기들 사이에서 중간역할을 할 수 있는 Manager를 추가해보자.

Item : Item 이 Manager를 갖고 있는 합성관계로 구현한 클래스(1/3) public abstract class Item { private String ID; public Item(String ID) { this.ID = ID; } public String getID() { return ID; abstract void printInfo(Object msg); Item 클래스의 멤버 ID의 Type을 String에서 int로 변경할 경우, 상속구조에서는 상속트리상의 모든 클래스의 수정이 필요하다. 그러나, Manager를 이용한 합성관계에서는 하위 클래스들의 수정대신 item클래스의 getID()의 return 값을 변경해주고 , manager에게 위임된 getID()를 호출함으로써 최상위 클래스의 변경에 대해 대비할 수도 있다. public class Item { private int ID; private ItemManager manager; public Item(ItemManager i) { this.itemmanager = i; } public int getID() { return manager.getID(); public String getName() { return manager.getName(); void printInfo(Object msg) { itemmanager.printInfo(msg); Item.java 생성자도 같이 변경해주자. ItemManager형태로 만들어지도록. getID()의 동작도 변경하자. ItemManager가 알아서 처리하도록.

Item : Item 이 Manager를 갖고 있는 합성관계로 구현한 클래스(2/3) //이 녀석의 역할은, 최상위클래스와 하위 클래스들, 기존의 데이터들이 서로 이해할 수 있도록 //최대한 중간역할을 해야한다. 현재 필요한 기능은 ‘자료형의 변환’!! abstract public class ItemManager { private String ID; public ItemManager(String ID) { this.ID = ID; } public void printInfo(Object msg) ; // 추상메소드 . 하위 클래스에서 각각 구현하도록. public int getID() { System.out.println("ID : Stirng -> Int"); return Integer.parseInt(ID); public String getName() { if(ID.startsWith(“1”)) return “Weapon”; if(ID.startsWith(“2”)) return “Armor”; if(ID.startsWith(“3”)) return “Boots”; return “defalut”; ItemManager.java public class Weapon extends ItemManager { public Weapon(String ID) { super(ID); } public void printInfo(Object msg) { System.out.println("--- 무기 종류 ---"); System.out.println(msg.toString()); //getClass(), getName() System.out.println("-----------------"); Weapon.java  생성자기능은 엄마에게 맡기고.!  현재 입력된 값을 숫자형으로 변환하여 return 해준다. Weapon을 수정했으므로, 기존의 Armor, boots는 크게 수정하지 않아도 됩니다.  1로 시작하는 것은 공격무기류, 2로 시작하면 방어류, 3으로 시작하면 부츠,,,등등… 의 정보를 알여주는 메소드도 추가한다.

Item : Item 이 Manager를 갖고 있는 합성관계로 구현한 클래스(3/3) public class ItemExample {      public static void main(String[] args) {       Item[] items = new Item[3];         items[0] = new Item(new Weapon(“101”)) ;       items[1] = new Item(new Amor(“202”));       items[2] = new Item(new Boots(“303"));                  for(int i = 0; i < items.length; i++) {                     printItemInfo(items[i]);         }    }   private static void printItemInfo(Item item) {     System.out.println("이 아이템의 ID는 " + item.getID() + "입니다."); item.printInfo(item.getName());         System.out.println(“!!");     } }  결과를 확인해보도록 합니다.

Item 정리 : 상속관계 vs. 합성관계의 차이 "상속"의 경우 상위 클래스의 멤버들의 타입이나 메소드가 변경되면 하위 클래스의 객체를 사용하는 클라이언트 코드를 모두 직접 수정해야만 했다. 하지만 "합성"의 경우, ItemManager 클래스가 Item클래스의 변경에 대해 유연하게 대처하는 역할을 수행하므로써, 하위클래스의 코드가 변경되지 않도록 할 수 있었다. 또한, 클라이언트 코드가 직접 ItemManager를 직접 사용하는 것이 아니라 Item의 메소드를 거쳐서 간접적으로 사용하기 때문에 ItemManager 클래스에서 수행하는 주요 메커니즘은 숨겨 보호할 수 도 있다. 위 예제와 달리, Item 클래스와 ItemManager클래스간의 유연한 결합으로 인해, ItemManager클래스의 메소드에서 어떠한 실수가 있다고 할지라도 이에 대응되는 Item 메소드의 내부코드를 수정하여 클라이언트 코드가 변경되지 않도록 할 수 있다. "상속"이 사용되는 대부분의 경우 "합성"으로 대체할 수 있다. 하지만 모든 경우 "상속" 대신 합성을 사용하는 것은 아님. 충분히 객체를 분석하고 설계하기로 하며, 상속"이 오용되었을 때 "합성"을 사용하여 수정할 수 있도록 구조를 익혀두도록.

과제#1 : Weapon/Player 클래스다이어그램 Tip 다양한 무기, 다양한 플레이어 만약 클래스들간에 IS-A 관계가 명확히 성립되면 "상속"을 사용한다. 만약 IS-A 관계가 아닌데 재사용할 클래스가 있는 경우에는 "합성"을 선택한다. 가장 먼저 해야 할 일은 만들어야 할 객체들의 ‘파악’ 그리고 ‘분류’입니다. 어떤 속성을 가지며 어떤 기능을 가지며 어떻게 동작하는가? 시간에 따라 변함이 없는가? 여러 역할을 가지고 있는가? 어떤 클래스가 다른 어떤 클래스에 대해서도 ‘A는 B다’ 테스트를 통과할 수 없다면 그냥 독립적인 클래스를 만듭니다. “더 구체적인 클래스”를 만들고 싶다면 하위클래스를!! . 하위클래스에서 사용할 틀(template)을 정의하고 싶다면, 그리고 구현 코드가 조금이라도 있으면 추상 클래스!! 상속 트리에서의 위치에 상관없이 어떤 클래스의 역할을 정의하고 싶다면 인터페이스를! !

정리

정리 : 인터페이스 서로 다른 상속 트리에서 같은 인터페이스를 구현할 수 있다. 한 클래스에서 여러 개의 인터페이스를 구현할 수도 있다. 그러나 다중상속의 대안으로 생각하지는 마세요. public class Dog extends Animal implements Pet, Saveable, Paintable {…} 인터페이스를 구현할 때는 implements라는 키워드를 씁니다. 한 클래스에서 여러 개의 인터페이스를 구현할 수 있습니다. 인터페이스와 클래스의 합성을 함께 사용해서 클래스의 유연성을 높이는 예들을 찾아보도록 하세요. GUI - 이벤트처리 부분에서 다시 보도록 하겠습니다.

정리 : 추상클래스 클래스를 만들 때 인스턴스를 만들 수 없게 하고 싶다면 abstract 키워드를 사용합니다. 추상 클래스에는 추상 메소드와 추상 메소드가 아닌 메소드를 모두 집어넣을 수 있습니다. 클래스에 추상 메소드가 하나라도 있으면 그 클래스는 추상 클래스로 지정해야 합니다. 추상 메소드에는 본체가 없으며 선언 부분은 세미콜론으로 끝납니다. 상속 트리에서 처음으로 나오는 일반 클래스에서는 반드시 모든 추상 메소드를 구현해야 합니다. 자바에 들어있는 모든 클래스는 직접 또는 간접적으로 Object의 하위클래스입니다..

서로 다른 클래스들간의 호환성, 유연성을 부여하는 방법에 대해 더 생각해보도록 하세요. ----(중략) OOP에서 동일한 메시지를 여러 사람에게 보냈을 때 받는 자의 객체에 따라 각각 적절한 절차가 이루어지는 것. 다태성(多態性) 또는 다상성(多相性)이라고도 한다. OOP에서는 하위 등급이 상위 등급의 특성을 계승할 때, 그 구조나 방법을 변경하거나 부분적으로 추가할 수 있으므로 동일 조작명(메소드이름)으로 다른 행동을 시킬 수 있다. --- 다형성을 부여하기 위하여 일부러 공통점이 없는 클래스들을 "상속" 관계로 묶으면 안된다. 공통된 인터페이스를 구현한 여러 클래스들을 통해서도 구현할 수 있기 때문이다. Public Interface IA{ … } Public Interface IB{ … } Public Class CA{ .. } Public Class CB{ .. } Public Interface IA extends IB{ … } public class CB implements IA extends CA { } public class Dog extends Animal implements Pet, Saveable, Paintable {…} 서로 다른 클래스들간의 호환성, 유연성을 부여하는 방법에 대해 더 생각해보도록 하세요.