๐Ÿ’ธ

์ธํ„ฐํŽ˜์ด์Šค

 

์ •์˜

  • ๋ชจ๋“  ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”์ƒ๋ฉ”์„œ๋“œ๋กœ ์„ ์–ธ๋จ public abstract(์•„๋ฌด๊ฒƒ๋„ ๋ถ™์ด์ง€ ์•Š์•„๋„) โ†’ Class์—์„œ implements์‹œ public ์•ˆ๋ถ™์—ฌ์ฃผ๋ฉด ์—๋Ÿฌ๊ฐ€ ์ƒ๊น€
  • ๋ชจ๋“  ๋ณ€์ˆ˜๊ฐ€ ์ƒ์ˆ˜๋กœ ์„ ์–ธ๋จ public static final
  • ๊ตฌํ˜„ ์ฝ”๋“œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ, ์ƒ์†์ด ์•„๋‹Œ Calculator๊ฐ€ Calc๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ (Class Diagram์—์„œ ์ ์„ ) ํ•จ
notion image
  • CompleteCalc๊ฐ€ Calc๋ฅผ ํƒ€์ž…์ƒ์†ํ–ˆ๋‹ค ๋ผ๊ณ  ๋งํ•จ. ๊ตฌํ˜„์ƒ์†๊ณผ๋Š” ๋‹ค๋ฆ„(๊ตฌํ˜„ ์ฝ”๋“œ๋ฅผ ๋ฐ›์€๊ฒƒ)
    • Calc calc = new CompleteCalc(); ๊ฐ€๋Šฅํ•จ
    • ๊ตฌํ˜„์ƒ์†์€ ์—ฌ๋Ÿฌ ํด๋ž˜์Šค๋ฅผ ๋‹ค์ค‘์ƒ์†ํ• ์ˆ˜์—†์Œ(๋ชจํ˜ธ์„ฑ ์กด์žฌ) โ† diamond problem
    • notion image
    • ํƒ€์ž…์ƒ์†์€ ์—ฌ๋Ÿฌ ํด๋ž˜์Šค๋ฅผ implements๋ฅผ ํ•  ์ˆ˜ ์žˆ์Œ(๋ชจํ˜ธ์„ฑ์ด ์—†์Œ. ์–ด์ฐจํ”ผ ๊ตฌํ˜„๋œ๊ฒƒ์ด ์—†๊ธฐ์—)

๊ธฐ๋Šฅ

  • ์ผ์ข…์˜ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์™€์˜ ์•ฝ์†์ด๋ฉฐ, ํด๋ž˜์Šค๋‚˜ ํ”„๋กœ๊ทธ๋žจ์ด ์ œ๊ณตํ•˜๋Š” ๋ช…์„ธ
  • ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ํ•˜๋‚˜์˜ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์ด๋ผ๋Š” ๊ฒƒ์€ ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค๋Š” ์˜๋ฏธ = ๊ตฌํ˜„์„ ๊ฐ•์ œํ•จ
  • ๋‹คํ˜•์„ฑ์„ ์ œ๊ณตํ•จ

์˜์กด์„ฑ ์—ญ์ „(Dependency Inversion)

  • ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ํšจ๊ณผ (์˜์กด์„ฑ์„ ์—ญ์ „)
public class Main{ public static void Main(String[] args){ new Main().run(LoginType.Naver); // LoginType - Enum } void run(LoginType loginType){ Login user = getLogin(loginType); user.login(); } // ์ด๊ฒŒ factory ํŒจํ„ด์ž„ private Login getLogin(LoginType type){ if (type == LoginType.Naver) return new NaverLogin(); return new KakaoLogin(); } }
public class UserService implements Login { private Login login; // ์˜์กด์„ฑ์„ ์™ธ๋ถ€์— ๋งก๊ธด๋‹ค๋ฉด, ์˜์กด๋„์œจ ๋‚ฎ์ถค // KakaoLogin, NaverLogin ๋“ฑ์˜ ๊ตฌ์ƒ์ฒด๋ฅผ ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด // ๊ฒฐํ•ฉ์„ฑ์ด ๋†’์•„์ง€๋Š” ๊ฒƒ์ž„ ์ถ”์ƒ์ฒด์™€ ๊ฒฐํ•ฉ์„ ํ•จ => ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์ง // ์˜์กด์„ฑ์„ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ ๋ฐ›์•˜๋‹ค => ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›์•˜๋‹ค // ์˜์กด์„ฑ ์ฃผ์ž„, Dependency Injection, DI // Dependency Inversion ๋จ (์–ด๋”˜๊ฐ€์— ์˜์กดํ•˜๊ฒŒ ๋  ๋•Œ, ๊ตฌ์ƒ์ฒด์— ์˜์กดํ•˜์ง€ ๋ง๊ณ  // ์ถ”์ƒ์ฒด์— ์˜์กดํ•ด๋ผ. ์˜์กด์„ฑ์„ ์—ญ์ „ํ•ด์„œ ์˜์กดํ•˜๋Š” ๊ฒƒ์ž„) public UserService(Login login){ this.login = login; } @Override public void login() { login.login(); } }
notion image
  • ์ด ๋ชจ๋“ˆ์ด ๋ฌด์Šจ ์ผ์„ ํ•˜๋Š” ์ง€์— ๋Œ€ํ•œ ๋ช…์„ธ. ์“ธ ๋•Œ ๊ทธ๊ฒŒ ์–ด๋–ป๊ฒŒ ๋Œ์•„๊ฐ€๋Š”์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†์œผ๋‹ˆ ์ด๋•Œ interface๊ฐ€ ๋งค์šฐ ํฐ ์—ญํ• ์„ ํ•จ. ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ๋Š” ์“ฐ๋Š” ๋ฐฉ์‹์ด ๋˜‘๊ฐ™์Œ

๋ถ€๊ฐ€ ๊ธฐ๋Šฅ

๋””ํดํŠธ ๋ฉ”์„œ๋“œ

  • ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹Œ ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คŒ
  • Adapter์˜ ์—ญํ• ์„ ํ•˜๊ฒŒ ๋จ(Adapter๋Š” interface์ƒ์— ์žˆ๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š” ์—†๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•˜์—ฌ ์‹ค์ œ ์ด์šฉํ•˜๋Š” ํด๋ž˜์Šค์™€ interface ์‚ฌ์ด์— ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ) โ‡’ default ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด Adapter๊ฐ€ ํ•„์š” ์—†๊ฒŒ ๋จ
public interface MyInterface{ void method1(); void method2(); default int method3() { return 42; } } public MyInterfaceAdapter implements MyInterface{ @Override void method1(); @Override void method2(); } public MyService implements MyInterface{ } // ์ด ์ƒํ™ฉ์—์„œ MyService๋Š” method1๋งŒ ์“ฐ๊ณ  ์‹ถ์€๋ฐ // ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์— ๋†“์ด๊ฒŒ ๋จ // ์ด ๋•Œ, MyInterface์— default๋ฅผ ๋‹ค ๋ถ™์ž„์œผ๋กœ์จ // ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ฉ”์„œ๋“œ๋งŒ overrideํ•ด์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•จ
  • ์ธํ„ฐํŽ˜์ด์Šค ์ถ”๊ฐ€ ๋งŒ์œผ๋กœ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Œ(default ๋ฉ”์„œ๋“œ๋กœ ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—)

๋žŒ๋‹ค์‹

  • ๋ฉ”์„œ๋“œ๋„ ์ต๋ช…์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ ํ•˜๋Š” ์ƒ๊ฐ์—์„œ ์ถœ๋ฐœ
  • ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ต๋ช… ํด๋ž˜์Šค๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ตฌ์กฐ์ž„
MyRunnable r1 = new MyRunnable(){ @Override public void run(){ System.out.println("Hello"); }; } MyRunnable r2 = () -> System.out.println("Hello"); // ๋žŒ๋‹คํ‘œํ˜„์‹(์ต๋ช…๋ฉ”์„œ๋“œ) // FunctionalInterface์ผ๋•Œ๋งŒ ์ด๋Ÿฐ์‹์œผ๋กœ ์„ ์–ธ์ด ๊ฐ€๋Šฅํ•จ. // ๊ตฌํ˜„๋ถ€๊ฐ€ ํ•œ์ค„ ๋ฐ–์—์—†์œผ๋ฉด {} ์ด๊ฒƒ๋„ ์ƒ๋žต ๊ฐ€๋Šฅํ•จ // ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํ•œ๊ฐœ๋ฉด () ๋„ ์ƒ๋žต ๊ฐ€๋Šฅํ•จ // ๋‹ค FunctionalInterface์ž„ MySupplier s = () -> "Hello World"; MyMapper m = (str) -> str.length(); // Method reference๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•จ // MyMapper m = String::length; MyConsumer c = i -> System.out.println(i); // System.out::println; MyRunnable r = () -> c.consume(m.map(s.supply())); // FunctionalInterface ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• void loop(int n, MyConsumer<Integer> consumer){ for(int i=0; i< n; i++){ consumer.consume(i); } } loop(10, System.out::println);

๋žŒ๋‹ค์‹ ์‚ฌ์šฉ ์‹œ, ์ฃผ์˜์ 

int strike = 0; int ball = 0; answer.indexedForEach((num, idx) -> { numbers.indexedForEach((num2, idx2) -> { if(!num.equals(num2)) return; if(idx.equals(idx2)) strike++; else ball++; }); });
  • FunctionalInterface ์•ˆ์—์„œ ๋ฐ”๊นฅ์˜ ๋ณ€์ˆ˜๋ฅผ ์ฝ์–ด์˜ฌ ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ๊ทธ ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜๋Š” ์—†์Œ. โ†’ ThreadSafe ํ•˜์ง€ ์•Š์Œ
  • MultiThread์—์„œ IndexedForEach๋ฅผ ํ†ตํ•ด์„œ ๊ฐ’์˜ ๋ณ€๊ฒฝ์ด ์žˆ๊ฒŒ ๋˜๋ฉด RaceCondition์ด ์ผ์–ด๋‚˜๊ฒŒ ๋จ
  • ๋™๊ธฐํ™” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์–ด์•ผํ•จ(AtomicInteger ์‚ฌ์šฉ)
public BallCount ballCount(Numbers answer, Numbers numbers){ AtomicInteger strike = new AtomicInteger(); AtomicInteger ball = new AtomicInteger(); answer.indexedForEach((num, idx) -> { numbers.indexedForEach((num2, idx2) -> { if(!num.equals(num2)) return; if(idx.equals(idx2)) strike.getAndIncrement(); else ball.getAndIncrement(); }); }); }

๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

  • ๋žŒ๋‹ค ํ‘œํ˜„์‹์—์„œ ์ž…๋ ฅ๋˜๋Š” ๊ฐ’์„ ๋ณ€๊ฒฝ ์—†์ด ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ (๊ฐœ๋ฐœ์ž์˜ ๊ฐœ์ž…์„ ์ฐจ๋‹จํ•จ์œผ๋กœ์จ ์•ˆ์ •์„ฑ์„ ์–ป์„ ์ˆ˜ ์žˆ์Œ. ๋ณ€๊ฒฝํ•˜์ง€ ๋ง๊ณ  ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ผ๋Š” ์˜์ง€์˜ ํ‘œํ˜„!!)
  • ์ตœ์ข…์œผ๋กœ ์ ์šฉ๋  ๋ฉ”์†Œ๋“œ์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” ํ‘œํ˜„ ๋ฐฉ์‹

์ œ๋„ˆ๋ฆญ

  • ์œ„์˜ ๊ฒฝ์šฐ์—์„œ ๋ฐ˜ํ™˜ ๋˜๋Š” output, input์˜ ํ˜•ํƒœ๋ฅผ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด์„œ๋Š”?? Generic ์‚ฌ์šฉ!!
public interface MySupplier<T> { T supply(); } public interface MyMapper<IN, OUT>{ OUT map(IN); } MySupplier<String> s = () -> "Hello World"; MyMapper<String, Integer> m = String::length;

์ต๋ช… ํด๋ž˜์Šค

  • ์ธํ„ฐํŽ˜์ด์Šค ์ด์šฉํ•˜๋ ค๋ฉด ํ•ญ์ƒ ๊ตฌํ˜„์„ ํ•ด์•ผ ํ•˜๊ธฐ์— ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. โ‡’ ๋ถˆํŽธํ•ด์„œ ํ•œ๋ฒˆ์— ํ•˜๋Š” ๊ฒƒ์ด ์ต๋ช… ํด๋ž˜์Šค
new Runnable(){ @Override public void run(){ //~~~~ } }.run();

private ๋ฉ”์„œ๋“œ

  • ์ธํ„ฐํŽ˜์ด์Šค ์•ˆ์— default ๋ฉ”์„œ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์„ ๋•Œ, private ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ
interface SomeInterface { void method1(); String method2(int i); default int method3() { return getNumber(); } default int method4() { return getNumber() + 22; } private int getNumber() { return 42; } }

์ธํ„ฐํŽ˜์ด์Šค use-case

ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ
  • public class A implements B, C {} ;
์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์ด์˜ ์ƒ์†
  • public interface MyInterface extends X, Y{};
  • extends ๋’ค์— ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ๋‚˜์˜ค๋ฉด ์–˜๋„ค๋“ค ๋‹ค ์ธํ„ฐํŽ˜์ด์Šค ์ธ๊ฒƒ.
ํด๋ž˜์Šค ์ƒ์†๊ณผ ์ธํ„ฐํŽ˜์ด์Šค ๊ฐ™์ด ์‚ฌ์šฉ(extends ๋จผ์ €, implementsํ›„์—)
  • public class BookShelf extends Shelf implements Queue{};

๋‹ค์ค‘ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„

  • ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๊ฐ€ ์ค‘๋ณต ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์—์„œ ์žฌ์ •์˜ ํ•˜์—ฌ์•ผ ํ•จ
public interface Buy { void buy(); default void order() { System.out.println("buy order"); } } public interface Sell { void sell(); default void order() { System.out.println("sell order"); } } public class Customer implements Buy, Sell{ @Override public void sell() { System.out.println("customer sell"); } @Override public void buy() { System.out.println("customer buy"); } @Override public void order() { System.out.println("customer order"); } public void hello() { System.out.println("hello"); } }

Static fields and methods

  • Java8 ์ดํ›„๋ถ€ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค ์•ˆ์— ์„ ์–ธ๋œ ๋ชจ๋“  ํ•„๋“œ๋Š” public, static, final ์ž„ โ†’ interface๊ฐ€ constant๋ฅผ ๋‘๊ธฐ์— ์ ํ•ฉํ•œ ์žฅ์†Œ๊ฐ€ ๋จ
  • ์ž๋ฐ” 8 ์ด์ „์—๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์  ๋ฉ”์„œ๋“œ ์„ ์–ธ์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Œ(๊ทธ๋ž˜์„œ Companion class ๊ฐ™์€ ๊ฒƒ์ด ๋งŒ๋“ค์–ด์กŒ์—ˆ์Œ)
  • ์ž๋ฐ” 8 ๋ถ€ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ •์  ๋ฉ”์„œ๋“œ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ. ์ž๋ฐ” 8์—์„œ๋Š” public ์ •์  ๋ฉค๋ฒ„๋งŒ ํ—ˆ์šฉํ•˜์ง€๋งŒ, ์ž๋ฐ” 9 ๋ถ€ํ„ฐ๋Š” private ์ •์  ๋ฉ”์„œ๋“œ๊นŒ์ง€๋Š” ํ—ˆ๋ฝํ•จ(private ๋ฉ”์„œ๋“œ๋„ ๊ฐ€๋Šฅํ•จ). ๊ทธ๋Ÿฌ๋‚˜ ์ •์  ํ•„๋“œ์™€ ์ •์  ๋ฉค๋ฒ„ ํด๋ž˜์Šค๋Š” ์—ฌ์ „ํžˆ public์ด์–ด์•ผ ํ•จ!