ํ๋ ์์ํฌ๋ฅผ ์ํ JAVA(3) - Java์ Interface
1. Interface์ ๊ธฐ๋ฅ
1๏ธโฃ ๊ตฌํ์ ๊ฐ์
2๏ธโฃ ๋คํ์ฑ ์ ๊ณต
๋คํ์ฑ์ ๊ณ ๋ คํ์ง ์์ ๊ฒฝ์ฐ
public class Main {
public static void main(String[] args) {
// ๋คํ์ฑ์ด ์์๋ - ๋ก๊ทธ์ธ์ ํ๊ณ ์ถ๋ค. -> ์ํฉ์ ๋ฐ๋ผ ์ธ์คํด์ค๋ฅผ ๋๊ฐ ๋ง๋ค๊ณ ์กฐ๊ฑด์ ๋ง๊ฒ ํธ์ถํด์ค์ผํ๋ค.
KakaoLogin KakaoUser = new KakaoLogin();
NaverLogin NaverUser = new NaverLogin();
KakaoUser.login();
NaverUser.login();
}
}
๋คํ์ฑ์ ์ด์ฉํด ๊ตฌํ
public class Main {
public static void main(String[] args) {
// ๋คํ์ฑ์ ์ด์ฉํ ๊ตฌํ
// **ํธ์คํธ ์ฝ๋** ์คํํ๋ ์ฝ๋๋ง ๊ฒฐ์ ์ ํ๋ค -> ์ค์ ํ์ผ, config
new Main().run(LoginType.Kakao)
}
// **๊ตฌํ์ฝ๋์์๋ ์๋ฌด๊ฒ๋ ๊ฒฐ์ ํ์ง ์์** : ์์ ์์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํจ
void run(LoginType loginType){
Login user = getLogin(loginType);
user.login();
}
private static Login getLogin(LoginType type){
if (type == LoginType.Kakao){
return new KakaoLogin();
}else{
return new NaverLogin();
}
}
}
3๏ธโฃ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ ํจ๊ณผ (์์กด์ฑ ์ญ์ )
package com.programmers.java.poly;
public class UserService implements Login{
private Login login; // ์บก์ํ
// ์์กด์ฑ์ ์ธ๋ถ์ ๋งก๊ฒจ ์์กด๋๋ฅผ ๋ฎ์ถ๋ค. -> ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ํํ ์ ์ฌ์ฑ์ ๊ฐ์ง
// ๊ตฌ์์ฒด์ ๊ฒฐํฉํ๋ฉด ๊ฒฐํฉ์ฑ ๊ฐํด์ง๋ค. => ์ถ์์ฒด์ ๊ฒฐํฉํ์ฌ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ค.
public UserService(Login login){ //์์กด์ฑ ์ฃผ์
, Dependency Injection
this.login = login;
}
@Override
public void login() {
login.login();
}
}
package com.programmers.java.poly;
public class Main {
public static void main(String[] args) {
UserService s = new UserService(new KakaoLogin());
s.login();
}
}
Dependency Inversion : ์์กด์ฑ ์ญ์
โ
Interface์ ๋ชจ๋ ๋ณ์๋ public static final
โ
Interface์ ๋ชจ๋ ๋ฉ์๋๋ public abstract
โ
ํ์
์ผ๋ก๋ ์ฌ์ฉ ๊ฐ๋ฅ. ์์ฑ์ X
์ธํฐํ์ด์ค์ ์ถ๊ฐ๋ ๊ธฐ๋ฅ๋ค ๐ : Java 8 ์ด์๋ถํฐ ๊ธฐ๋ฅ ๊ฐํ
2. Default method ๊ธฐ๋ฅ
default ๋ฉ์๋ : default ํค์๋๋ฅผ ์ธํฐํ์ด์ค๊ฐ ๊ตฌํ์ฒด๋ฅผ ๊ฐ์ง ์ ์๊ฒ ๋์๋ค.
๊ฐ๋
package com.programmers.java.defualt;
interface MyInterface {
void method1(); // ์ถ์๋ฉ์๋
default void sayHello(){ // default ํค์๋๋ฅผ ํตํด ๊ตฌํ์ฒด๋ฅผ ๊ฐ์ง
System.out.println("Hello World");
}
}
public class Main implements MyInterface{
public static void main(String[] args) {
new Main().sayHello();
}
// @Override // ์ค๋ฒ๋ผ์ด๋ ๊ฐ๋ฅ
// public void sayHello(){
// System.out.println("override hello");
// }
//
@Override
public void method1() {
throw new RuntimeException();
}
}
ํ์ฉ
1. Adapter ์ญํ ์ ํ๊ฒ ๋์๋ค.
: interface ๋ฉ์๋์ค ์ผ๋ถ๋ง ํ์ํ ๊ฒฝ์ฐ ๋น๋ฉ์๋๋ฅผ ๊ตฌํํด ๋์ Adapter๋ฅผ ๋ง๋ค์ด ๋๊ณ ์์๋ฐ์ผ๋ฉด ๋น ๋ฉ์๋๋ค์ ๊ตฌํํด๋ ํ์์์ด ๊น๋ํ๊ฒ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
: ํ์ง๋ง class ๋ ํ๋์ class ๋ง ์์ํ ์ ์๊ธฐ๋๋ฌธ์ ์ด๋ฏธ ์์์ ๋ฐ์ ๊ฒฝ์ฐ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
⇒ Default method๋ฅผ ํตํด adapter๋ฅผ ๋ง๋ค ํ์์์ด์ก๋ค.
// MyInterfaceAdapter.java
package com.programmers.java.default2;
public class MyInterfaceAdapter implements MyInterface{
@Override
public void method1() {
}
@Override
public void method2() {
}
}
package com.programmers.java.default2;
public class Main {
public static void main(String[] args) {
new Service().method1(); // method1๋ง ์ฌ์ฉํ๊ณ ์ถ์
}
// Interface ๋ฉ์๋๋ฅผ ์ ๋ถ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ Adapter๋ฅผ ๋ง๋ค์ด(๋น ๋ฉ์๋๋ก ๊ตฌํ๋จ) ์์๋ฐ์์ ์ํ๋ ๋ฉ์๋๋ง ์ค๋ฒ๋ผ์ด๋ฉ ํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
// Adapter๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์์์ ํ๋๋ง ๋ฐ์ ์ ์๊ธฐ๋๋ฌธ์ ์ด๋ฏธ ๋ค๋ฅธ ๊ณณ์ ์์ ๋ฐ์์ ๊ฒฝ์ฐ ์ฌ์ฉํ์ง ๋ชปํ๋ค.
class Service extends MyInterfaceAdapter{
@Override
public void method1(){
System.out.println("Hello");
}
}
// => ๊ทธ๋ด ๊ฒฝ์ฐ interface method๋ฅผ ์ ๋ถ defualt๋ก ๋ง๋ ํ ์ํ๋ ๋ฉ์๋๋ง ์ค๋ฒ๋ผ์ด๋ฉ ํ๋ฉด ๊ฐ์ ์ฑ์ด ์์ด ์ฝ๋๋ฅผ ์ํ๋ ๋ฉ์๋๋ง ๊น๋ํ๊ฒ ์ ์ง ๊ฐ๋ฅ
2. interface ์ถ๊ฐ๋ง์ผ๋ก ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์๊ฒ ๋์๋ค.
package com.programmers.java.default3;
interface Flyable {
default void fly(){
System.out.println("fly");
}
}
interface Swimmable {
default void swim(){
System.out.println("swim");
}
}
interface Wolkable{
default void wolk(){
System.out.println(("wolk"));
}
}
package com.programmers.java.default3;
class Duck implements Flyable,Wolkable,Swimmable{}
class Swan implements Flyable,Swimmable{}
public class Main {
public static void main(String[] args) {
new Duck().fly();
new Swan().swim();
}
}
3. static ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค. : ํจ์ ์ ๊ณต์(๊ทธ๋ฆ)๊ฐ ๋๋ค. → ์ ํธ๋ฆฌํฐ๋ฅผ ์์ฑํ ์ ์๋ค.
package com.programmers.java.default3;
interface Ability{
static void sayHello(){
System.out.println("Hello");
}
}
public class Main {
public static void main(String[] args) {
Ability.sayHello();
}
}
3. Functional Interface
๋ฉ์๋ : class์ ์ข ์๋ ํจ์
- ์ถ์ ๋ฉ์๋๊ฐ ํ๋๋ง ์กด์ฌํ๋ ์ธํฐํ์ด์ค @FuncionalInterface
package com.programmers.java.func;
@FunctionalInterface
public interface MyRunnable {
void run(); // ์ถ์๋ฉ์๋๊ฐ ํ๋๋ฐ์ ์๋ ๋ฉ์๋ == ํจ์ํ ์ธํฐํ์ด์ค
}
@FunctionalInterface
interface MyMap{
void map();
default void sayHello(){
System.out.println("Hello World");
}
static void sayBye(){
System.out.println("Bye World");
}
}
4. Lambda ํํ์
โ ์ธํฐํ์ด์ค ์์์์ฑ
- ์ต๋ช ํด๋์ค๋ฅผ ์ฌ์ฉํด์ ์ธํฐ์ฒด์ด์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๊ตฌํ์ ๋ฐ๋ก ์ ์ํ๋ค.
: ์๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ฌด์กฐ๊ฑด class๋ฅผ ์์ฑํด implements ํด์ค์ผ new๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ์์ฑ, ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
⇒ ์ต๋ช ํด๋์ค๋ฅผ ํตํด ์ด๋ฆ์๋ ํด๋์ค๋ฅผ ์์ฑํด์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
package com.programmers.java.func;
public class Main {
public static void main(String[] args) {
new MyRunnable(){
@Override
public void run() {
System.out.println("run");
}
}.run();
}
}
: ์ธํฐํ์ด์ค๋ฅผ ์ต๋ช ์ผ๋ก ์์ฑํ ์ ์๋ค๋ฉด ๋ฉ์๋๋ ์ต๋ช ์ผ๋ก ๋ง๋ค ์ ์์๊น?
- ์ต๋ช ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ํํํ๋ ๋ฐฉ๋ฒ ⇒ ๋๋ค ํํ์
- ์ต๋ช ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๊ฐ๊ฒฐํ๊ฒ ์ธํฐํ์ด์ค ์ธ์คํด์ค ์์ฑ ๋ฐฉ๋ฒ.
- functional interface์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
package com.programmers.java.func;
public class Main2 {
public static void main(String[] args) {
// 1. functional interface๋ฅผ ์ต๋ช
๊ฐ์ฒด๋ก ๋ง๋ค ๊ฒฝ์ฐ ๋ฌด์กฐ๊ฑด ํ๋์ method๋ฅผ override๋ฅผ ํด์ค์ผํ๋ค.
MyRunnable r = new MyRunnable() {
@Override
public void run() {
System.out.println("run");
}
};
r.run();
// 2. ์ด์ฐจํผ ํ๋์ ๋ฉ์๋๋ง override ํด์ค์ผํ๊ฒ ๋๋ฌธ์ ๋ ๊ฐ๋จํ๊ฒ ํํํ ์ ์๋ค. => ์ต๋ช
๋ฉ์๋
// ๊ตฌํ๋ถ๊ฐ ํ์ค์ผ ๊ฒฝ์ฐ {} ์๋ต๊ฐ๋ฅ. return๋ ์๋ต๊ฐ๋ฅ
MyRunnable r2 = () -> {
System.out.println("run~~~");
};
}
}
- ๋ฉ์๋ ๋ ํผ๋ฐ์ค
: ๋๋ค ํํ์์์ ์ ๋ ฅ๋๋ ๊ฐ์ ๋ณ๊ฒฝ์์ด ๋ฐ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
: ์ ๋ ฅ๊ฐ์ ๋ณ๊ฒฝํ์ง ๋ง๋ผ๋ ์์ง์ ํํ ๋ฐฉ์์ด๊ธฐ๋ ํ๋ค. → ๊ฐ๋ฐ์์ ๊ฐ์ ์ ์ฐจ๋จํ์ฌ ์์ ์ฑ ์ป๊ธฐ
: ์ต์ข ์ ์ผ๋ก ์ ์ฉ๋ ๋ฉ์๋์ ๋ ํผ๋ฐ์ค๋ฅผ ์ง์ ํด ์ฃผ๋ ํํ ๋ฐฉ์
MyConsummer c = (str) -> System.out.println(str);
MyConsummer c = System.out::println;
- ์ ๋ค๋ฆญ
: ์ธ์ ํน์ ๋ฆฌํด๊ฐ์ ์ ๋์ ์ผ๋ก ๋ณ๊ฒฝ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
: reference type๋ง ์ฌ์ฉ๊ฐ๋ฅ
@FunctionalInterface
public interface MyMapper<IN, OUT> {
OUT map(IN s);
}
@FunctionalInterface
public interface MySupplier<T> {
T supply();
}
public class Main {
public static void main(String[] args) {
MySupplier<String> s = () -> "Hello";
MyMapper<String,Integer> m = (str) -> str.length(); //reference type๋ง ๊ฐ๋ฅํด์ Integer
Systme.out.println(m.map(s.supply()));
}
}
์์ ๊ฐ์ด ์์ฃผ ํ์ฉํ ์ ์๋ Functional Interface๋ค์ java.util.function์์ ์ ๊ณต๋๋ค.
https://docs.oracle.com/javase/8/docs/api/
Java Platform SE 8
docs.oracle.com
ํ์ฉ ์
package com.programmers.java.lambda;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class Main3 {
public static void main(String[] args) {
new Main3().filteredNumbers(30,
i -> i % 3 == 0 && i > 0,
System.out::println
);
// ๊ธฐ๋ฅ์ ํธ์คํธ์๊ฒ ๋งก๊ฒจ ๋ค์ํ๊ฒ ์ฌ์ฉ์ํ ๊ฐ๋ฅํ๋ค.
}
void filteredNumbers(int max, Predicate<Integer> p, Consumer<Integer> c) {
for (int i = 0; i < max; i++) {
if (p.test(i)) c.accept(i);
}
}
}
'Back-end ๋ฐ๋ธ์ฝ์ค > week 01 - 02 TIL (java, DB)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] 221024 - ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์๊ฐ (0) | 2022.10.24 |
---|---|
[TIL] 221021 - Java ์ค์ต ํ๋ก์ ํธ : ์ซ์์ผ๊ตฌ ๊ฒ์ (0) | 2022.10.21 |
[TIL] 221020 - Java์ Collection (0) | 2022.10.21 |
[TIL] 221018 - Java์ OOP (2) | 2022.10.18 |
[TIL] 221017 - Java ๊ฐ๋ฐ ํ๊ฒฝ ๊ตฌ์ถ (0) | 2022.10.18 |
๋๊ธ