๊ฐ ์ƒˆ ๋ฒ„์ „์˜ Java๋Š” ์ด์ „ ๋ฒ„์ „๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋ฃฌ ์ž๋ฃŒ์—์„œ ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์˜ ์˜ˆ๋กœ enumsJava 5 ์ด์ „์—๋Š” ์–ธ์–ด๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ - 1
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Java 8์€ Java 7๊ณผ ๋ˆˆ์— ๋„๊ฒŒ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์šฐ๋ฆฌ๋Š” ์ค‘์š”ํ•œ ํ˜์‹ ์„ ๋ฌด์‹œํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋‹จ์›์—์„œ ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์–ธ์–ด์— ๋Œ€ํ•œ ํ•œ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ์ธ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค . ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋™์ž‘์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค . ๊ทธ ๋ชฉ์ ์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ๊ฐœ์ฒด์— ์–ด๋–ค ๋™์ž‘์ด ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค . ๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋ฐœ์ž๋Š” ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ๋ชจ๋“  ํด๋ž˜์Šค์—์„œ ๋™์ผํ•œ ์ƒํ™ฉ์— ์ž์ฃผ ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ž˜๋œ ์ž๋™์ฐจ์˜ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public interface Car {

   public void gas();
  
   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class Truck implements Car {

   @Override
   public void go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}
์ด ์ฝ”๋“œ์˜ ์ฃผ์š” ๋ฌธ์ œ๋Š” ๋ฌด์—‡์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ๋‹น์‹ ์€ ์•„๋งˆ๋„ ์šฐ๋ฆฌ๊ฐ€ ๋งŽ์€ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„์ฐจ๋ ธ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ด๋ฉฐ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Java 8์ด ์ถœ์‹œ๋˜๊ธฐ ์ „์—๋Š” ํŠน๋ณ„ํ•œ ์†”๋ฃจ์…˜์ด ์—†์—ˆ๋‹ค๋Š” ๊ฒƒ์€ ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. Java 8์ด ์ถœ์‹œ๋˜์—ˆ์„ ๋•Œ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ ํ•˜๊ณ  ์ธํ„ฐํŽ˜์ด์Šค ๋‚ด์—์„œ ๋ฐ”๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

public interface Car {

   public default void gas() {
       System.out.println("Gas!");
   }

   public default void brake() {
       System.out.println("Brake!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
์ด์ œ ๋ชจ๋“  ์ž๋™์ฐจ์— ๋™์ผํ–ˆ๋˜ gas()๋ฐ brake()๋ฉ”์†Œ๋“œ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ด๋™๋˜์–ด ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฉ”์„œ๋“œ๋Š” ๊ฐ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
๋ฉ”์„œ๋“œ ๊ฐ€ ์žˆ๋Š” 100๊ฐœ์˜ ํด๋ž˜์Šค๊ฐ€ ์žˆ์ง€๋งŒ gas()๊ทธ ์ค‘ 99๊ฐœ๋งŒ ๋™์ผํ•œ ๋™์ž‘์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ๊ทธ๊ฒŒ ๋ชจ๋“  ๊ฒƒ์„ ๋ง์น˜๋‚˜์š”? ์ด ๊ฒฝ์šฐ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ๋ฌผ๋ก  ์•„๋‹™๋‹ˆ๋‹ค :) ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class UnusualCar implements Car {
   @Override
   public void go() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car slows down differently!");
   }
}
๋‹ค๋ฅธ 99๊ฐœ ์œ ํ˜•์˜ ์ž๋™์ฐจ๋Š” ๋ชจ๋‘ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€๋งŒUnusualCarํด๋ž˜์Šค๋Š” ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค. ํฐ ๊ทธ๋ฆผ์„ ๋ง์น˜์ง€ ์•Š๊ณ  ์นจ์ฐฉํ•˜๊ฒŒ ์ž์‹ ์˜ ํ–‰๋™์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋‹ค์ค‘ ์ƒ์†. ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๋“ฏ์ด Java์—๋Š” ๋‹ค์ค‘ ์ƒ์†์ด ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ๊ฐ•์˜์—์„œ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. C++์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ๋Š” ์ƒํ™ฉ์ด ๋ฐ˜๋Œ€์ž…๋‹ˆ๋‹ค. ๋™์ผํ•œ ๊ฐœ์ฒด๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋‹ค๋ฅธ ํŠน์„ฑ๊ณผ ๋™์ž‘์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์ค‘ ์ƒ์†์€ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๋ฅผ ์ œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์šฐ๋ฆฌ๋Š” ๋ถ€๋ชจ์—๊ฒŒ ์ž๋…€, ๊ต์‚ฌ์—๊ฒŒ ํ•™์ƒ, ์˜์‚ฌ์—๊ฒŒ ํ™˜์ž์ž…๋‹ˆ๋‹ค. ์‹ค์ƒํ™œ์—์„œ ์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ํ–‰๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ์šฐ๋ฆฌ๋Š” ์นœํ•œ ์นœ๊ตฌ์™€ ๋‹ค๋ฅด๊ฒŒ ๊ต์‚ฌ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์ƒํ™ฉ์„ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•ด ๋ด…์‹œ๋‹ค. Pond์™€ Aviary๋ผ๋Š” ๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ด…์‹œ๋‹ค. ์—ฐ๋ชป์—๋Š” ํ—ค์—„์น˜๋Š” ์ƒˆ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์ƒˆ์žฅ์—๋Š” ๋‚ ์•„๋‹ค๋‹ˆ๋Š” ์ƒˆ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ๋‘ ๊ฐœ์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.FlyingBird๊ทธ๋ฆฌ๊ณ  Waterfowl.

public class Waterfowl {
}

public class FlyingBird {
}
๋”ฐ๋ผ์„œ ๋ฌผ๋ ค๋ฐ›์€ ์ƒˆ๋Š” ์กฐ๋ฅ˜ ์‚ฌ์œก์žฅ์œผ๋กœ ๋ณด๋‚ด๊ณ  FlyingBirdํŒŒ์ƒ๋œ ์ƒˆ๋Š” Waterfowl์—ฐ๋ชป์œผ๋กœ ๊ฐ‘๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ๊ฐ„๋‹จ ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์–ด๋””์„ ๊ฐ€ ์˜ค๋ฆฌ๋ฅผ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ์˜ค๋ฆฌ๋Š” ํ—ค์—„์น˜๊ณ  ๋‚ ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๋‹ค์ค‘ ์ƒ์†์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ Java๋Š” ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๋ถ€๋ชจ๋ฅผ ์ƒ์†ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค! ์šฐ๋ฆฌ ์˜ค๋ฆฌ๋Š” ๋‚ ์•„๋‹ค๋‹ˆ๋Š” ์ƒˆ์ผ ์ˆ˜๋„ ์žˆ๊ณ  ํ—ค์—„์น˜๋Š” ์ƒˆ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค :) ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ make FlyingBird์™€ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์žˆ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.Waterfowl

public class Duck implements FlyingBird, Waterfowl {

   // Methods of both interfaces combine easily into one class
  
   @Override
   public void fly() {
       System.out.println("Flying!");
   }

   @Override
   public void swim() {

       System.out.println("Swimming!");
   }
}
์ด๊ฒƒ์€ ์šฐ๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์ด ์ˆ˜์—…์„ ์œ ์—ฐํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์„ ์œ ์ง€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•๊ณผ ๊ฒฐํ•ฉํ•˜๋ฉด ๊ฐœ์ฒด์˜ ๋™์ž‘์„ ๊ฒฐ์ •ํ•˜๋Š” ๋Šฅ๋ ฅ์ด ๊ฑฐ์˜ ๋ฌดํ•œํ•ด์ง‘๋‹ˆ๋‹ค! :)