πŸ“‚ JAVA/μ£Όμš” κ°œλ…

μΈν„°νŽ˜μ΄μŠ€(Interface)

Amenable 2023. 6. 13. 10:29

  JDK1.8λΆ€ν„° λ””ν΄νŠΈ λ©”μ„œλ“œμ™€ static λ©”μ„œλ“œλ„ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ‚¬μš©ν•  수 있게 λ˜μ—ˆλ‹€.

  일단은 JDK1.8 μ΄μ „μ˜ μΈν„°νŽ˜μ΄μŠ€μ— λŒ€ν•΄μ„œ λ¨Όμ € μ‚΄νŽ΄λ³΄κ³ , 그리고 JDK1.8μ—μ„œ μΆ”κ°€λœ κΈ°λŠ₯(λ””ν΄νŠΈ λ©”μ„œλ“œ, static λ©”μ„œλ“œ)κ³Ό Java9λΆ€ν„° μ‚¬μš©ν•  수 μžˆλŠ” private λ©”μ„œλ“œμ— λŒ€ν•΄μ„œ μ‚΄νŽ΄λ³΄λŠ” κ²ƒμœΌλ‘œ ν•˜μž.

 

 

πŸ“™ 1. μΈν„°νŽ˜μ΄μŠ€λž€

  μΈν„°νŽ˜μ΄μŠ€λž€ μΌμ’…μ˜ μΆ”μƒν΄λž˜μŠ€μ΄λ‹€. μΈν„°νŽ˜μ΄μŠ€λŠ” μΆ”μƒν΄λž˜μŠ€μ²˜λŸΌ μΆ”μƒλ©”μ„œλ“œλ₯Ό κ°–μ§€λ§Œ μΆ”μƒν΄λž˜μŠ€λ³΄λ‹€ 좔상화 정도가 λ†’μ•„μ„œ μΆ”μƒν΄λž˜μŠ€μ™€ 달리 λͺΈν†΅μ„ κ°–μΆ˜ 일반 λ©”μ„œλ“œ λ˜λŠ” λ©€λ²„λ³€μˆ˜λ₯Ό κ΅¬μ„±μ›μœΌλ‘œ κ°€μ§ˆ 수 μ—†λ‹€. 였직 μΆ”μƒλ©”μ„œλ“œμ™€ μƒμˆ˜λ§Œμ„ λ©€λ²„λ‘œλ§Œ κ°€μ§ˆ 수 있으며, κ·Έ μ™Έμ˜ λ‹€λ₯Έ μ–΄λ– ν•œ μš”μ†Œλ„ ν—ˆμš©ν•˜μ§€ μ•ŠλŠ”λ‹€.

 

  μΈν„°νŽ˜μ΄μŠ€λ„ μΆ”μƒν΄λž˜μŠ€μ²˜λŸΌ μ™„μ„±λ˜μ§€ μ•Šμ€ λΆˆμ•ˆμ „ν•œ 것이기 λ•Œλ¬Έμ— κ·Έ 자체만으둜 μ‚¬μš©λ˜κΈ°λ³΄λ‹€λŠ” λ‹€λ₯Έ 클래슀λ₯Ό μž‘μ„±ν•˜λŠ”λ° 도움을 쀄 λͺ©μ μœΌλ‘œ μž‘μ„±λœλ‹€.

 

 

πŸ“™ 2. μΈν„°νŽ˜μ΄μŠ€μ˜ μ‚¬μš©λ²•

πŸ“Œ 1. μΈν„°νŽ˜μ΄μŠ€ μž‘μ„±

public interface PlayingCard {

    public static final int SPADE = 4;

    public abstract String getCardNumber();
}

  일반적인 클래슀의 멀버듀과 달리 μΈν„°νŽ˜μ΄μŠ€μ˜ 멀버듀은 λ‹€μŒκ³Ό 같은 μ œμ•½μ‚¬ν•­μ΄ μžˆλ‹€.

  • λͺ¨λ“  λ©€λ²„λ³€μˆ˜λŠ” public static final 이어야 ν•˜λ©°, 이λ₯Ό μƒλž΅ν•  수 μžˆλ‹€.
  • λͺ¨λ“  λ©”μ„œλ“œλŠ” public abstract 이어야 ν•˜λ©°, 이λ₯Ό μƒλž΅ν•  수 μžˆλ‹€.

  μΈν„°νŽ˜μ΄μŠ€μ— μ •μ˜λœ λͺ¨λ“  멀버에 μ˜ˆμ™Έ 없이 μ μš©λ˜λŠ” 사항이기 λ•Œλ¬Έμ— μ œμ–΄μžλ₯Ό μƒλž΅ν•  수 μžˆλŠ” 것이며, νŽΈμ˜μƒ μƒλž΅ν•˜λŠ” κ²½μš°κ°€ λ§Žλ‹€. μƒλž΅λœ μ œμ–΄μžλŠ” μ»΄νŒŒμΌ μ‹œμ— μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μ μœΌλ‘œ μΆ”κ°€ν•΄ μ€€λ‹€.

public interface PlayingCard {

    public static final int SPADE = 4;
    final int DIAMOND = 3; // public static final int DIAMOND = 3;
    static int HEART = 2; // public static final int HEART = 2;
    int CLOVER =1 ; // public static final int DIAMOND = 1;

    public abstract String getCardNumber();
    String getCardKind(); // public abstract String getCardKind();
}

πŸ“Œ 2. κ΅¬ν˜„

  μΈν„°νŽ˜μ΄μŠ€λ„ μΆ”μƒν΄λž˜μŠ€μ²˜λŸΌ 상속받은 μžμ†ν΄λž˜μŠ€κ°€ μ˜€λ²„λΌμ΄λ”©μ„ 톡해 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•¨μœΌλ‘œμ¨ μ‚¬μš©ν•  수 μžˆλ‹€. λ‹€λ§Œ ν΄λž˜μŠ€λŠ” ν™•μž₯ν•œλ‹€λŠ” 의미의 ν‚€μ›Œλ“œ 'extends'λ₯Ό μ‚¬μš©ν•˜μ§€λ§Œ μΈν„°νŽ˜μ΄μŠ€λŠ” κ΅¬ν˜„ν•œλ‹€λŠ” 의미의 ν‚€μ›Œλ“œ 'implements'λ₯Ό μ‚¬μš©ν•  뿐이닀.

public interface Movable {

    void move(int x, int y);
}

public class Player implements Movable {

    @Override
    public void move(int x, int y) {
        System.out.println("(" + x + ", " + y + ") 둜 움직인닀!");
    }
}

public static void main(String[] args) {
    Player player = new Player();
    player.move(1, 2); // (1, 2) 둜 움직인닀!
}

  ν•œ κ°€μ§€ μ£Όμ˜ν•  점은 move()λ₯Ό μ˜€λ²„λΌμ΄λ”©ν•  λ•Œ μ ‘κ·Ό μ œμ–΄μžλ₯Ό λ°˜λ“œμ‹œ public으둜 ν•΄μ•Ό ν•œλ‹€. Movableμ—μ„œ 'void move(int x, int y)'라고 μ„ μ–Έν•˜μ˜€μ§€λ§Œ 'public abstract'κ°€ μƒλž΅λœ 것이기 λ•Œλ¬Έμ— μ‹€μ œλ‘œλŠ” 'public abstract void move(int x, int y)'이닀.

  μ˜€λ²„λΌμ΄λ”© ν•  λ•ŒλŠ” μ‘°μƒμ˜ λ©”μ„œλ“œλ³΄λ‹€ 넓은 λ²”μœ„μ˜ μ ‘κ·Ό μ œμ–΄μžλ₯Ό μ§€μ •ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— move()λ₯Ό κ΅¬ν˜„ν•  λ•Œμ—λŠ” μ ‘κ·Ό μ œμ–΄μžλ₯Ό λ°˜λ“œμ‹œ public으둜 ν•΄μ•Ό ν•œλ‹€λŠ” 것이닀.

πŸ“Œ 3. 상속

  μΈν„°νŽ˜μ΄μŠ€λŠ” μΈν„°νŽ˜μ΄μŠ€λ‘œλΆ€ν„°λ§Œ 상속받을 수 있으며, ν΄λž˜μŠ€μ™€λŠ” 달리 닀쀑상속, 즉 μ—¬λŸ¬ 개의 μΈν„°νŽ˜μ΄μŠ€λ‘œλΆ€ν„° 상속을 λ°›λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. 

public interface Movable {

    void move(int x, int y);
}

public interface Attackable {

    void attack(Unit u);
}

public interface Fightable extends Movable, Attackable { }

 

 

πŸ“™ 3. μΈν„°νŽ˜μ΄μŠ€μ˜ μž₯점

πŸ“Œ 1. ν‘œμ€€ν™”κ°€ κ°€λŠ₯ν•˜λ‹€.

  ν”„λ‘œμ νŠΈμ— μ‚¬μš©λ˜λŠ” κΈ°λ³Έ 틀을 μΈν„°νŽ˜μ΄μŠ€λ‘œ μž‘μ„±ν•œ λ‹€μŒ, κ°œλ°œμžλ“€μ—κ²Œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λ„λ‘ ν•¨μœΌλ‘œμ¨ 보닀 μΌκ΄€λ˜κ³  μ •ν˜•ν™”λœ ν”„λ‘œκ·Έλž¨μ˜ 개발이 κ°€λŠ₯ν•˜λ‹€.

πŸ“Œ 2. μ„œλ‘œ κ΄€κ³„μ—†λŠ” ν΄λž˜μŠ€λ“€μ—κ²Œ κ΄€κ³„λ₯Ό λ§Ίμ–΄ μ€„ μˆ˜ μžˆλ‹€.

  μ„œλ‘œ 상속관계에 μžˆμ§€λ„ μ•Šκ³ , 같은 μ‘°μƒν΄λž˜μŠ€λ₯Ό κ°€μ§€κ³  μžˆμ§€ μ•Šμ€ μ„œλ‘œ μ•„λ¬΄λŸ° 관계도 μ—†λŠ” ν΄λž˜μŠ€λ“€μ—κ²Œ ν•˜λ‚˜μ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ³΅ν†΅μ μœΌλ‘œ κ΅¬ν˜„ν•˜λ„λ‘ ν•¨μœΌλ‘œμ¨ 관계λ₯Ό λ§Ίμ–΄ 쀄 수 μžˆλ‹€.

public interface Repairable { }

class SCV extends GroundUnit implements Repairable { }
class Tank extends GroundUnit implements Repairable { }
class Dropship extends AirUnit implements Repairable { }

  GroundUnit인 SCV와 Tank, 그리고 AirUnit인 DropShip이 μ„œλ‘œ 관계가 μ—†λŠ” ν΄λž˜μŠ€μ΄μ§€λ§Œ Repairable μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν†΅ν•΄μ„œ μˆ˜λ¦¬κ°€ κ°€λŠ₯ν•œ μœ λ‹›μ΄λΌκ³  관계λ₯Ό 맺어쀄 수 μžˆλ‹€.

 

πŸ“Œ 3. 독립적인 ν”„λ‘œκ·Έλž˜λ°μ΄ κ°€λŠ₯ν•˜λ‹€.

  μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•˜λ©΄ 클래슀의 μ„ μ–Έκ³Ό κ΅¬ν˜„μ„ λΆ„λ¦¬μ‹œν‚¬ 수 있기 λ•Œλ¬Έμ— μ‹€μ œκ΅¬ν˜„μ— 독립적인 ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. 

  ν΄λž˜μŠ€μ™€ 클래슀 κ°„μ˜ 직접적인 관계λ₯Ό μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•΄μ„œ 간접적인 κ΄€κ³„λ‘œ λ³€κ²½ν•˜λ©΄, ν•œ 클래슀의 변경이 κ΄€λ ¨λœ λ‹€λ₯Έ ν΄λž˜μŠ€μ— 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠλŠ” 독립적인 ν”„λ‘œκ·Έλž˜λ°μ΄ κ°€λŠ₯ν•˜λ‹€.

πŸ“Œ 4. κ°œλ°œμ‹œκ°„μ„ λ‹¨μΆ•μ‹œν‚¬ μˆ˜ μžˆλ‹€.

  일단 μΈν„°νŽ˜μ΄μŠ€κ°€ μž‘μ„±λ˜λ©΄, 이λ₯Ό μ‚¬μš©ν•΄μ„œ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” μͺ½μ—μ„œλŠ” λ©”μ„œλ“œμ˜ λ‚΄μš©μ— 관계없이 μ„ μ–ΈλΆ€λ§Œ μ•Œλ©΄ 되기 λ•Œλ¬Έμ΄λ‹€.

  그리고 λ™μ‹œμ— λ‹€λ₯Έ ν•œμͺ½μ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 클래슀λ₯Ό μž‘μ„±ν•˜κ²Œ 되면, μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν΄λž˜μŠ€κ°€ μž‘μ„±λ  λ•ŒκΉŒμ§€ 기닀리지 μ•Šκ³ λ„ μ–‘μͺ½μ—μ„œ λ™μ‹œμ— κ°œλ°œμ„ μ§„ν–‰ν•  수 μžˆλ‹€.

 

 

πŸ“™ 4. μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” μ΄μœ 

  μ§€κΈˆκΉŒμ§€ μΈν„°νŽ˜μ΄μŠ€μ˜ νŠΉμ§•κ³Ό κ΅¬ν˜„ν•˜λŠ” 방법, μž₯점 λ“± μΈν„°νŽ˜μ΄μŠ€μ— λŒ€ν•œ 일반적인 사항듀에 λŒ€ν•΄μ„œ λͺ¨λ‘ μ‚΄νŽ΄λ³΄μ•˜λ‹€.

  ν•˜μ§€λ§Œ 'μΈν„°νŽ˜μ΄μŠ€λž€ λ„λŒ€μ²΄ 무엇인가?'λΌλŠ” μ˜λ¬Έμ€ μ—¬μ „νžˆ λ‚¨μ•„μžˆμ„ 것이닀. κ·Έλž˜μ„œ μ΄λ²ˆμ—λŠ” μΈν„°νŽ˜μ΄μŠ€μ˜ κ·œμΉ™μ΄λ‚˜ ν™œμš©μ΄ μ•„λ‹Œ, 본질적인 츑면에 λŒ€ν•΄μ„œ ν•œλ²ˆ μ‚΄νŽ΄λ³΄μž.

  μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œ μ•„λž˜ 2κ°€μ§€ 사항을 염두에 두고 μžˆμ–΄μ•Ό ν•œλ‹€.

  1. 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” μͺ½(User)κ³Ό ν΄λž˜μŠ€λ₯Ό μ œκ³΅ν•˜λŠ” μͺ½(Provider)이 μžˆλ‹€.
  2. λ©”μ„œλ“œλ₯Ό μ‚¬μš©(호좜)ν•˜λŠ” μͺ½(User)μ—μ„œλŠ” μ‚¬μš©ν•˜λ €λŠ” λ©”μ„œλ“œ(Provider)의 μ„ μ–ΈλΆ€λ§Œ μ•Œλ©΄ λœλ‹€. (λ‚΄μš©μ€ λͺ°λΌλ„ λœλ‹€.)

  클래슀 A와 클래슀 Bκ°€ λ‹€μŒκ³Ό 같이 μžˆλ‹€κ³  ν•˜μž.

class A {
    public void methodA(B b) {
        b.methodB();
    }
}

class B {
    public void methodB() {
        System.out.println("methodB()");
    }
}

public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.methodA(new B());
    }
}

  클래슀 A와 클래슀 BλŠ” μ„œλ‘œ 직접적인 관계가 μžˆλ‹€. 클래슀 Aλ₯Ό μž‘μ„±ν•˜λ €λ©΄ 클래슀 Bκ°€ μž‘μ„±λ˜μ–΄ μžˆμ–΄μ•Ό ν•˜κ³ , 클래슀 B의 methodB()의 μ„ μ–ΈλΆ€κ°€ λ³€κ²½λ˜λ©΄ 이λ₯Ό μ‚¬μš©ν•˜λŠ” 클래슀 A도 λ³€κ²½λ˜μ–΄μ•Ό ν•œλ‹€.

  즉, 직접적인 κ΄€κ³„μ˜ 두 ν΄λž˜μŠ€λŠ” ν•œμͺ½(Provider)이 λ³€κ²½λ˜λ©΄ λ‹€λ₯Έ ν•œμͺ½(User)도 λ³€κ²½λ˜μ–΄μ•Ό ν•œλ‹€λŠ” 단점이 μžˆλ‹€.

 

  κ·ΈλŸ¬λ‚˜ 클래슀 Aκ°€ 클래슀 Bλ₯Ό 직접 ν˜ΈμΆœν•˜μ§€ μ•Šκ³  μΈν„°νŽ˜μ΄μŠ€λ₯Ό 맀개체둜 ν•΄μ„œ 클래슀 Aκ°€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν†΅ν•΄μ„œ 클래슀 B의 λ©”μ„œλ“œμ— μ ‘κ·Όν•˜λ„λ‘ ν•˜λ©΄, 클래슀 B에 변경사항이 μƒκΈ°κ±°λ‚˜ 클래슀 B와 같은 κΈ°λŠ₯의 λ‹€λ₯Έ 클래슀둜 λŒ€μ²΄λ˜μ–΄λ„ 클래슀 AλŠ” μ „ν˜€ 영ν–₯을 λ°›μ§€ μ•Šλ„λ‘ ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€.

class A {

    // 클래슀 BλŒ€μ‹  μΈν„°νŽ˜μ΄μŠ€ Iλ₯Ό 이용
    public void methodA(I i) {
        i.methodB();
    }
}

interface I {
    public abstract void methodB();
}

class B implements I{

    @Override
    public void methodB() {
        System.out.println("methodB in B class");
    }
}

public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.methodA(new B());
    }
}

  μ΄λ ‡κ²Œ μž‘μ„±ν•˜λ©΄ 클래슀 A와 클래슀 BλŠ” 'A-B'의 직접적인 κ΄€κ³„μ—μ„œ 'A-I-B'의 간접적인 κ΄€κ³„λ‘œ λ°”λ€Œκ²Œ λœλ‹€. 클래슀 AλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν†΅ν•΄ μ‹€μ œλ‘œ μ‚¬μš©ν•˜λŠ” ν΄λž˜μŠ€μ˜ μ΄λ¦„을 λͺ°λΌλ„ λ˜κ³  μ‹¬μ§€μ–΄λŠ” μ‹€μ œλ‘œ κ΅¬ν˜„λœ ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„도 λ¬Έμ œ λ˜μ§€ μ•ŠλŠ”λ‹€.

 

  mainμ½”λ“œμ—μ„œ 확인할 수 μžˆλ“―μ΄ μ§€κΈˆμ€ λ§€κ°œλ³€μˆ˜λ₯Ό ν†΅ν•΄μ„œ μΈν„°νŽ˜μ΄μŠ€ Iλ₯Ό κ΅¬ν˜„ν•œ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ™μ μœΌλ‘œ μ œκ³΅λ°›κ³  μžˆλ‹€. ν•˜μ§€λ§Œ μ•„λž˜μ™€ κ°™μ΄ μ œ3의 ν΄λž˜μŠ€λ₯Ό ν†΅ν•΄μ„œ μ œκ³΅λ°›μ„ μˆ˜ μžˆλ‹€. (JDBC의 DriverManager ν΄λž˜μŠ€κ°€ μ΄λŸ° λ°©μ‹μœΌλ‘œ λ˜μ–΄ μžˆλ‹€.)

class A {

    // 제 3의 클래슀의 λ©”μ„œλ“œλ₯Ό ν†΅ν•΄μ„œ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ–»μ–΄μ˜¨λ‹€.
    public void methodA() {
        I i = InstanceManager.getInstance();
        i.methodB();
    }
}

interface I {
    public abstract void methodB();
}

class B implements I {

    @Override
    public void methodB() {
        System.out.println("methodB in B class");
    }
}

class InstanceManager {

    public static I getInstance() {
        return new B();
    }
}

public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.methodA();
    }
}

  μ΄λ ‡κ²Œ ν•˜λ©΄ μΈμŠ€ν„΄μŠ€λ₯Ό 직접 μƒμ„±ν•˜μ§€ μ•Šκ³ , getInstance()λΌλŠ” λ©”μ„œλ“œλ₯Ό 톡해 μ œκ³΅λ°›λŠ”λ‹€. 그러면 λ‚˜μ€‘에 λ‹€λ₯Έ ν΄λž˜μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λ³€κ²½λ˜μ–΄λ„ A클래슀의 λ³€κ²½ 없이 getInstance()만 λ³€κ²½ν•˜λ©΄ λœλ‹€λŠ” μž₯점이 μžˆλ‹€.

class InstanceManager {

    public static I getInstance() {
        return new B();
        
        // return new C(); // λ³€κ²½ κ°€λŠ₯
        // return new D(); // λ³€κ²½ κ°€λŠ₯
    }
}

 

 

πŸ“™ 5. λ””ν΄νŠΈ λ©”μ„œλ“œ & static λ©”μ„œλ“œ (from JDK1.8)

  JDK1.8λΆ€ν„° 생긴 κΈ°λŠ₯듀에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž. μ›λž˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ— 좔상 λ©”μ„œλ“œλ§Œ μ„ μ–Έν•  수 μžˆλŠ”λ°, JDK1.8λΆ€ν„° λ””ν΄νŠΈ λ©”μ„œλ“œμ™€ staticλ©”μ„œλ“œλ„ μΆ”κ°€ν•  수 있게 λ˜μ—ˆλ‹€.

πŸ“Œ 1. λ””ν΄νŠΈ λ©”μ„œλ“œ

  쑰상 ν΄λž˜μŠ€μ— μƒˆλ‘œμš΄ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” 것은 λ³„λ‘œ 큰 λ¬Έμ œκ°€ λ˜μ§€ μ•Šμ§€λ§Œ, μΈν„°νŽ˜μ΄μŠ€μ˜ κ²½μš°μ—λŠ” 큰 λ¬Έμ œκ°€ λœλ‹€. μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•œλ‹€λŠ” 것은, 좔상 λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•œλ‹€λŠ” 것이고, 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 기쑴의 λͺ¨λ“  ν΄λž˜μŠ€λ“€μ΄ μƒˆλ‘œ μΆ”κ°€λœ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 

  이λ₯Ό ν•΄κ²°ν•˜κ³ μž λ””ν΄νŠΈ λ©”μ„œλ“œ(default method)λΌλŠ” 것이 λ‚˜μ™”λ‹€.

  λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” 좔상 λ©”μ„œλ“œμ˜ 기본적인 κ΅¬ν˜„μ„ μ œκ³΅ν•˜λŠ” λ©”μ„œλ“œλ‘œ, 좔상 λ©”μ„œλ“œκ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ μƒˆλ‘œ μΆ”κ°€λ˜μ–΄λ„ ν•΄λ‹Ή μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 클래슀λ₯Ό λ³€κ²½ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

public interface MyInterface {

    void walk();
    default void fly() {
        System.out.println("Let's Fly!!");
    };
}

  λ””ν΄νŠΈ λ©”μ„œλ“œ μ—­μ‹œ μ ‘κ·Ό μ œμ–΄μžκ°€ public이며, μƒλž΅κ°€λŠ₯ν•˜λ‹€.

 

  μƒˆλ‘œ μΆ”κ°€λœ λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ 기쑴의 λ©”μ„œλ“œμ™€ 이름이 μ€‘λ³΅λ˜μ–΄ μΆ©λŒν•˜λŠ” κ²½μš°κ°€ λ°œμƒν•œλ‹€. 이 μΆ©λŒμ„ ν•΄κ²°ν•˜λŠ” κ·œμΉ™μ€ λ‹€μŒκ³Ό κ°™λ‹€.

  • μ—¬λŸ¬ μΈν„°νŽ˜μ΄μŠ€μ˜ λ””ν΄νŠΈ λ©”μ„œλ“œ κ°„μ˜ μΆ©λŒ
    μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€μ—μ„œ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μ˜€λ²„라이딩해야 ν•œλ‹€.
  • λ””ν΄νŠΈ λ©”μ„œλ“œμ™€ μ‘°μƒ ν΄λž˜μŠ€μ˜ λ©”μ„œλ“œ κ°„μ˜ μΆ©λŒ
    쑰상 ν΄λž˜μŠ€μ˜ λ©”μ„œλ“œκ°€ μƒμ†λ˜κ³ , λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” λ¬΄μ‹œλœλ‹€.

  μ΄λŸ¬ν•œ 점을 κ³ λ €ν•˜κΈ° λ²ˆκ±°λ‘­λ‹€λ©΄, κ·Έλƒ₯ ν•„μš”ν•œ μͺ½μ˜ λ©”μ„œλ“œμ™€ 같은 λ‚΄μš©μœΌλ‘œ μ˜€λ²„λΌμ΄λ”©ν•˜λ©΄ λœλ‹€.

πŸ“Œ 2. static λ©”μ„œλ“œ

  사싀 static λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€μ™€ 관계가 μ—†λŠ” 독립적인 λ©”μ„œλ“œμ΄κΈ° λ•Œλ¬Έμ— μ˜ˆμ „λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€μ— μΆ”κ°€ν•˜μ§€ λͺ»ν•  μ΄μœ κ°€ μ—†μ—ˆλ‹€. κ·ΈλŸ¬λ‚˜ μžλ°”λ₯Ό 보닀 μ‰½κ²Œ 배울 수 μžˆλ„λ‘ κ·œμΉ™μ„ λ‹¨μˆœνžˆ ν•  ν•„μš”κ°€ μžˆμ–΄μ„œ μΈν„°νŽ˜μ΄μŠ€μ˜ λͺ¨λ“  λ©”μ„œλ“œλŠ” 좔상 λ©”μ„œλ“œμ΄μ–΄μ•Ό ν•œλ‹€λŠ” κ·œμΉ™μ— μ˜ˆμ™Έλ₯Ό 두지 μ•Šμ•˜λ‹€.

  κ·Έλž˜μ„œ μΈν„°νŽ˜μ΄μŠ€μ™€ κ΄€λ ¨λœ static λ©”μ„œλ“œλŠ” λ³„λ„μ˜ ν΄λž˜μŠ€μ— λ”°λ‘œ 두어야 ν–ˆλ‹€. (java.util.Collection μΈν„°νŽ˜μ΄μŠ€μ™€ Collections 클래슀)

 

  JDK1.8λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€μ—μ„œλ„ static λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 있게 λ˜μ—ˆλ‹€. μΈν„°νŽ˜μ΄μŠ€ μ „μš© static λ©”μ„œλ“œλΌκ³  ν•΄μ„œ μΌλ°˜ ν΄λž˜μŠ€μ˜ static λ©”μ„œλ“œμ™€ λ‹€λ₯Έ κ²ƒμ΄ μ—†κ³  κ°™μ€ λ°©λ²•μœΌλ‘œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

public interface MyInterface {

    public static void explain() {
        System.out.println("MyInterface의 explain() λ©”μ„œλ“œμž…λ‹ˆλ‹€.");
    }
}

public static void main(String[] args) {
    MyInterface.explain();
}

 

 

πŸ“™ 6. private λ©”μ„œλ“œ (from Java9)

  μžλ°” 9λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€μ—μ„œ private λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 있게 λ˜μ—ˆλ‹€. μΈν„°νŽ˜μ΄μŠ€μ— default, static λ©”μ„œλ“œκ°€ 생긴 이후, μ΄λŸ¬ν•œ λ©”μ„œλ“œλ“€μ˜ λ‘œμ§μ„ κ³΅ν†΅ν™”ν•˜κ³  μž¬μ‚¬μš©ν•˜κΈ° μœ„ν•΄ 생긴 λ©”μ„œλ“œλ‹€.
  private λ©”μ„œλ“œλ„ κ΅¬ν˜„λΆ€λ₯Ό κ°€μ Έμ•Ό ν•œλ‹€. 단, private λ©”μ„œλ“œλŠ” μΈν„°νŽ˜μ΄μŠ€ λ‚΄λΆ€μ—μ„œλ§Œ λŒμ•„κ°€λŠ” μ½”λ“œμ΄λ‹€. μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©ν•˜κ±°λ‚˜ μž¬μ •μ˜ ν•  수 μ—†λ‹€.

  λ”°λΌμ„œ μΈν„°νŽ˜μ΄μŠ€ λ‚΄λΆ€μ—μ„œ private λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ, default λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ ν˜ΈμΆœν•΄μ•Ό ν•˜λ©°, 만일 private static ν‚€μ›Œλ“œλ₯Ό 뢙인 λ©”μ„œλ“œλŠ” static λ©”μ„œλ“œμ—μ„œλ§Œ 호좜이 κ°€λŠ₯ν•˜λ‹€.

public interface MyInterface {

    default void callPrivateMethod() {
        privateMethod();
    }

    private void privateMethod() {
        System.out.println("private λ©”μ„œλ“œμž…λ‹ˆλ‹€.");
    }

    static void callPrivateStaticMethod() {
        privateStaticMethod();
    }

    private static void privateStaticMethod() {
        System.out.println("private static λ©”μ„œλ“œμž…λ‹ˆλ‹€.");
    }
}

 

ν•΄λ‹Ή 글은
남ꢁ성 λ‹˜μ˜ 'μžλ°”μ˜ 정석',
geeksforgeeks 의 'Private Methods in Java 9 Interfaces',
Inpa λ‹˜μ˜ 'μΈν„°νŽ˜μ΄μŠ€(Interface) 문법 & ν™œμš© - μ™„λ²½ κ°€μ΄λ“œ'
λ₯Ό μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.