Software Architect
[OOAD] 캡슐화, 상속, 다형성, Interface 등
이반&핫버드
2022. 3. 21. 21:21
캡슐화
캡슐
- 데이터, 필드
- 허용하는 데이터/필드로만, 데이터 제어 가능
- 허용하지 않는 데이터/필드 접근 막음 >> 은닉
캡슐화 장점
- Server code가 허용한 방법대로 Client code를 작성하도록 유도
코드 적용 예
package com.company;
public class Main {
public static void main(String[] args) {
System.out.println("Hello");
GameMachine gm = new GameMachine();
gm.inputCoin(5);
gm.playGame();
gm.currentStatus();
}
}
class GameMachine{
private int totalCoin = 0; // [1] //
public void inputCoin(int a) {
if (a > 10 || a < -10) { // [2] //
System.out.println("Error!! Coin is too big");
return;
}
if (a + totalCoin > 5) {
System.out.println("Error!! Max");
}
totalCoin += a;
}
public void playGame(){
totalCoin -= 1;
}
public void currentStatus() {
System.out.println(totalCoin);
}
}
- [1] private로 접근하지 못하도록 막아둠
- [2] Client에서 어떻게 사용해도 버그가 발생하지 않도록 처리
상속
개요
- 상속 : 부모가 가진 요소드를 자식이 물려받아 사용
- OOP 상속
: 부모/자식 관계로 보기 어려움
: 코드 중복 방지를 위해 공통적인 요소를 일반화 시킴
>> 중복된 메서드/필드 = 변경 시 모두 수정 필요 -> 버그 유발
코드 적용 예
package com.company;
public class Main {
public static void main(String[] args) {
SpeedRobot spr = new SpeedRobot();
spr.stop();
//spr.run();
SmartRobot smr = new SmartRobot();
smr.stop();
smr.sitDown();
}
}
class Robot {
int hp;
void stop() { System.out.println("Parent-Stop"); } // [1] //
void move() { System.out.println("Parent-Move"); }
}
class SpeedRobot extends Robot { // [2] //
int modelID;
void stop() { System.out.print("Re-Stop"); }
void run () { System.out.print("Run"); }
void Walk() { System.out.print("Walk"); }
}
class PowerRobot extends Robot {
int mana;
void attack() { System.out.print("Attack"); }
void jump () { System.out.print("Jump" ); }
}
class SmartRobot extends Robot{
int IQ;
void fly() { System.out.print("Fly"); }
void sitDown() { System.out.print("SitDown"); }
void StandUp() { System.out.print("StandUp"); }
}
- [1] 중복 되는 부분을 Class로 작성
- [2] 중복 되는 Class 부분을 사용하는 Class 사용 = extends
- Super Class / Derived Class (분류/파생)
Base Class / Sub Class (기원/종류)
객체와 분류 관계
- "is a" 관계
- "is a kind of" 관계
- 객체와 분류
Overloading / Overriding
- Overriding = Suppler Class 메서드 재정의
- Overloading = 동일한 이름의 메서드, 다른 Argument로 함수 구분
코드 적용 예
public class SpeedRobot extends Robot {
int modelID = 10;
void move() { System.out.println("Fast run"); } // [1] //
void move(int i) { System.out.println("run =" + i); } // [2] //
void run() {}
void walk() {}
}
- Super class인 Robot Class의 move()를 다시 정의 -> Overriding
- [1], [2]와 같이 동일한 이름, 다른 argument의 메서드
다형성
개요
- 다형성 = 한 객체가 다양한 타입을 담을 수 있는 형태
- 상속관계 구현하여 다형성 적용
코드 적용 예
package com.company;
public class Main {
public static void main(String[] args) {
Rifle rf = new Snifer();
rf.shot();
rf = new Shotgun();
rf.shot();
}
}
class Rifle {
void shot() { System.out.println("RIFLE"); } // [1] //
}
class Shotgun extends Rifle {
void shot() { System.out.println("SHOTGUN"); } // [2] //
}
class Snifer extends Rifle {
void shot() { System.out.println("SNIPER"); } // [3] //
}
- Super Class의 메서드 [1]을 Deriverd Class의 메서드 [2]를 재정의
Interface
개요
- 내부에 접근하기 위한 공통적 형태
- 사용자는 Interface만 알고 있으면 쉽게 함수 사용 가능
Interface 사용하는 이유
- 확장 가능한 형태
- 객체를 쉽게 사용하고자 표준화 시킴
코드 적용 예
package com.company;
public class Main {
static Socket factory(String name) {
if (name == "Dansang") return new Dansang();
if (name == "Samsang") return new Samsang();
if (name == "SunPower") return new SunPower();
return null;
}
static void TVShow(Socket s) {
s.plugin();
System.out.println("Watching TV");
}
public static void main(String[] args) {
TVShow(new Dansang());
Socket s = factory("Samsang");
TVShow(s);
TVShow(factory("SunPower"));
}
}
interface Socket { // [1] //
void plugin();
void unplugin();
}
class Samsang implements Socket {
@Override // [2] //
public void plugin() { System.out.println("Plugin-Samsang"); }
@Override
public void unplugin() { System.out.println("UnPlugin-Samsang"); }
private void enable330V() { System.out.println("330V Start"); }
private void diable330V(){ System.out.println("330V Stop"); }
}
class SunPower implements Socket { // [3] //
@Override
public void plugin() { System.out.println("Plugin-Sun"); }
@Override
public void unplugin() { System.out.println("UnPlugin-Sun"); }
private void enableSun() { System.out.println("Sun Start"); }
private void disableSun() { System.out.println("Sun Stop"); }
}
class Dansang implements Socket {
@Override
public void plugin() { System.out.println("Plugin-Dansang"); }
@Override
public void unplugin() { System.out.println("UnPlugin-Dansang"); }
private void enable220() { System.out.println("Sun 220"); }
private void disable220() { System.out.println("Sun 220"); }
}
- Interface [1]에 명시된 메서드는 [2]와 같이 반드시 구현 해야 함
- Samsng은 Socket이라는 Interface 규격을 따름 -> Realization
- Interface 실체화 = implements