Polymorphism
Java μ Polymorphism (λ€νμ±) μ νλμ κ°μ²΄λ₯Ό μ¬λ¬ νμ μΌλ‘ λνλ΄κ² νμ¬ λ€μν κΈ°λ₯μΌλ‘ μ΄μ©ν μ μλλ‘ νλκ²μ΄λ€.
μ΄λ μ½λμ μ μ°νλ©° μ¬μ¬μ©μ΄ κ°λ₯νλλ‘ κ΅¬νλλ©° ν¬κ² Dispatch λ°©λ²μ λ°λΌ Static Dispatch μ Dynamic Dispatch λ‘ λλλ€.
Dispatch
νλ‘κ·Έλ¨μ΄ μ΄λ€ λ©μλλ₯Ό νΈμΆν κ²μΈκ°λ₯Ό κ²°μ νμ¬ κ·Έκ²μ μ€ννλ κ³Όμ μ λ§νλ€.
Static Dispatch
Static Dispatch λ νλ‘κ·Έλ¨μ΄ μ»΄νμΌ μμ μ μμ μμΌλ©° λνμ μΌλ‘ Method Overloading μ΄ μλ€.
Method Overloading (λ©μλ μ€λ²λ‘λ©)
κ°μ μ΄λ¦μ λ©μλλ₯Ό μ¬λ¬κ° μ μνκ³ λ§€κ°λ³μμ μ νκ³Ό κ°μλ₯Ό λ€λ₯΄κ² νμ¬ λ€μν μ νμ νΈμΆμ μλ΅νλ λ°©λ²μ΄λ€.
μ΄λ Function Signature λ₯Ό λ€λ₯΄κ² νμ¬ μ¬μ©νλ λ°©λ² μΌλ‘ Method Signature κ° λμΌνλ©΄ μ¬μ©μ΄ λΆκ°νλ€.
public class Dispatch {
static class Service {
void run() {
System.out.println("run");
}
void run(String msg) {
System.out.println(msg);
}
}
public static void main(String[] args) {
new Service().run();
}
}
μ μ½λμ main()
λ©μλλ₯Ό μ€ννκ² λλ©΄ Service
ν΄λμ€μ run()
λ©μλμ€ μ΄λκ²μ΄ μ€νλλμ§λ λ°νμμ΄ μλ μ»΄νμΌ μμ μ μ μ μλ€.
μ»΄νμΌ μμ μ μ μ μμΌλ―λ‘ μ΄λ€ λ©μλκ° νΈμΆλ μ§λ μ»΄νμΌμ΄ μ’ λ£λ ν λ°μ΄νΈ μ½λμλ λλ¬λκ² λμ΄ μλ€.
Dynamic Dispatch
νΉμ λ©μλλ ν¨μ ꡬνμ΄ νλ‘κ·Έλ¨μ λ°νμμ κ²°μ λλ κ²μΌλ‘ λνμ μΌλ‘λ Method Overriding μ΄ μλ€.
μ μ λμ€ν¨μΉ (static dispatch) μ λΉν΄μλ λλ¦¬κ³ μ»΄νμΌλ¬μ μ΅μ νλ₯Ό λ§μ λΉμ©μ΄ λ ν¬κ² λ°μλ μ μλ€.
Method Overriding (λ©μλ μ€λ²λΌμ΄λ©)
μμ ν΄λμ€κ° κ°μ§κ³ μλ λ©μλλ₯Ό νμ ν΄λμ€κ° μ¬ μ μ νμ¬ μ¬μ©νλ κ²
public class Dispatch {
static abstract class Service {
abstract void run();
}
static class MyServcie1 extends Service {
@Overried
void run() {
System.out.println("MyService 1");
}
}
static class MyService2 extends Service {
@Overried
void run() {
System.out.println("MyService 2");
}
}
public static void main(String[] args) {
Service svc = new MyService1();
svc.run()
}
}
μ μ½λμ μ΄λ€ ν΄λμ€μ run()
λ©μλκ° μ€νλ μ§λ μ»΄νμΌ μμ μλ μ μ μλ€.
λ€μ΄λλ―Ή λμ€ν¨μΉμ 리μλ² νλΌλ©ν°μ μν λ©μλ νΈμΆμ μ¬μ©νλ κ°μ²΄ λ³μμ μν΄ κ²°μ λλκ²μΌλ‘ νλΌλ©ν° νμ μ μν΄ κ²°μ λλ κ²μ΄ μλλ€.
Method Signature (λ©μλ μκ·Έλμ²)
λ©μλμ μ΄λ¦ (Method Name) κ³Ό 맀κ°λ³μμ νμ (Parameter Types) μ΄ κ°μΌλ©΄ λ©μλ μκ·Έλμ²κ° κ°λ€κ³ νλ€.
WARNING
λ°νκ°μ νμ (Return Type) μ λ©μλ μκ·Έλμ²μ ν¬ν¨λμ§ μλλ€.
Function Signature (ν¨μ μκ·Έλμ²)
ν¨μμ μνμ λͺ
μλλ 맀κ°λ³μμ 리μ€νΈλ₯Ό κ°λ₯΄ν¨λ€.
λ ν¨μμ 맀κ°λ³μμ κ°―μ μ νμ
μ΄ κ°μΌλ©΄ λ ν¨μμ μκ·Έλμ²λ κ°λ€κ³ ν μ μμ΅λλ€.
int sum (int a, int b, double c);
int sum2 (int, int, double);
μ λ ν¨μμ μκ·Έλμ²κ° κ°λ€.
μκ·Έλμ²κ° κ°μ ν¨μλ κ°μ ν¨μ ν¬μΈν°μ μν΄ μνΈνΈνμ΄ κ°λ₯νλ€.
Double Dispatch
μ±κΈ λμ€ν¨μΉμ΄ μ¬λ¬λ² μΌμ΄λλ κ²μ΄ λλΈ λμ€ν¨μΉμ΄λ€.
interface Game {
void play(Play play);
}
static class Init implements Game{
@Override
public void play(Play play) {
play.run(this);
}
}
static class Score implements Game {
@Override
public void play(Play play) {
play.run(this);
}
}
interface Play {
void run(Init init);
void run(Score score);
}
static class Puzzle implements Play {
@Override
public void run(Init init) {
System.out.println("Init Puzzle");
}
@Override
public void run(Score score) {
System.out.println("Score Puzzle");
}
}
static class Action implements Play {
@Override
public void run(Init init) {
System.out.println("Init Action");
}
@Override
public void run(Score score) {
System.out.println("Score Action");
}
}
@Test
public void doubleDispatch() {
List<Game> games = Arrays.asList(new Init(), new Score());
List<Play> play = Arrays.asList(new Puzzle(), new Action());
games.forEach(g -> play.forEach(p -> g.play(p)));
}
β Encapsulation SOLID β