#5. ์๋ฐ์ Interface
by JiwonDev# Abstract Class (์ถ์ ํด๋์ค)
์ฐธ๊ณ ๋ก ํด๋์ค ๋ด๋ถ์ ๊ตฌํ๋ถ๊ฐ ์๊ณ , ์ ์ธ๋ง ๋์ด์๋ ๊ฒ์ Abstract Method(์ถ์ ๋ฉ์๋) ๋ผ๊ณ ํ๋ค. ์ถ์ ๋ฉ์๋๊ฐ ์กด์ฌํ๋ ํด๋์ค๋ abstract ํค์๋๋ฅผ ์ด์ฉํด ๋ฐ๋์ ์ถ์ ํด๋์ค๋ก ๋ง๋ค์ด์ผ ํ๋ค. ๊ฐ์ฒด์ ์ธ์คํด์ค๊ฐ ์์ฑ๋์ง ์๊ฒ ๋ฐฉ์งํ๊ธฐ ์ํจ์ด๋ค.
public abstract class Animal {
public abstract String getFood();
}
์ฌ๋ฐ๋ ์ ์ ์ถ์๋ฉ์๋๊ฐ ํ๋๋ผ๋ ์์ผ๋ฉด ๋ฐ๋์ ํ์ํด์ฃผ์ด์ผ ํ์ง๋ง, ์ถ์๋ฉ์๋๊ฐ ์๋๋ผ๋ ๊ฐ์ฒด์ ์ธ์คํด์ค ์์ฑ์ ๋ฐฉ์งํ๊ธฐ ์ํด abstract class๋ฅผ ์ ์ธ ํ ์๋ ์๋ค. ์ด๋ Math ๊ฐ์ด ๊ตณ์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค ํ์๊ฐ ์๋ ํด๋์ค ๋ฑ์ ์ฌ์ฉ๋๋ค.
# Interface
์ธํฐํ์ด์ค๋ ์ถ์ ํด๋์ค์ ์ผ์ข ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค. ๋ค๋ง ์ด๋ฆ์์ ์ ์ถ ํ ์ ์๋ฏ์ด, ์ธํฐํ์ด์ค ๋ด๋ถ์๋ ์ถ์ ๋ฉ์๋(public abstract)์ ์์(static final)๋ง ์ฌ์ฉ ํ ์ ์๋ค.
interface MyInterface{
public static final int MY_VALUE = 10;
int MT_VALUE2 = 10; // ์ธํฐํ์ด์ค์์๋ ์๋์ผ๋ก ์์ํ (static final) ๋๋ค.
public abstract myMethod();
// ์ธํฐํ์ด์ค์์๋ abstract ํค์๋๋ฅผ ์๋ตํด๋ ์ ๋ถ public abstract๋ก ๊ฐ์ฃผํ๋ค.
// ์๋ 3๊ฐ๋ ์ ๋ถ public abstract ์ด๋ค.
public abstract myMethod1();
public myMethod2() ;
myMethod3() ;
}
# Default Method
๋ค๋ง ๊ธฐ์กด ์๋ฐ์์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํจ์ ์์ด, ์ฌ์ฉํ์ง ์๋ ์ถ์ ๋ฉ์๋๋ ์ ๋ถ ๊ตฌํํด์ฃผ์ด์ผ ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์๊ธฐ์ ๋ถํธํจ์ด ๋ง์๋ค. ๊ทธ๋์ Java8 ๋ถํฐ๋ default ํค์๋๋ฅผ ์ด์ฉํ์ฌ ๊ธฐ๋ณธ ๊ตฌํ ๊ฐ์ ์ ์ ์ ์๊ฒ ํด์ฃผ์๋ค.
package com.company;
public interface Foo {
void printName(); // ์ถ์๋ฉ์๋ 1
String getName(); // ์ถ์๋ฉ์๋ 2
// ์ด๋ฐ์์ผ๋ก default ํค์๋๋ฅผ ์ด์ฉํด ๊ธฐ๋ณธ๊ฐ์ ์ ์ ์ ์๋ค.
default void printNameUpperCase(){
System.out.println(getName().toUpperCase());
}
}
ํ์ง๋ง defalut ๋ฉ์๋๋ฅผ ๋๋ฌด ๋ฏฟ๊ณ ์ฌ์ฉํ๊ธฐ์๋ ์ฝ๋์ ์์ ์ฑ์ ๋ณด์ฅํ ์ ์๊ธฐ์ ์ธํฐํ์ด์ค์ JavaDoc์ ์ ์ฝ์ด๋ณด๊ณ ํ์ํ๋ค๋ฉด ๊ธฐ๋ณธ ๋ฉ์๋๋ฅผ @Overrideํด์ ์ฌ์ฉํ๋๋ก ํ์.
public interface Foo {
/**
* @implSpec
* ์ด ๊ตฌํ์ฒด๋ getName()์ผ๋ก ๊ฐ์ ธ์จ ๋ฌธ์์ด์ ๋๋ฌธ์๋ก ๋ฐ๊ฟ ์ถ๋ ฅํ๋ค.
*/
default void printNameUpperCase(){
System.out.println(getName().toUpperCase());
}
}
์ฐธ๊ณ ๋ก Object์์ ์ ๊ณตํ๋ ๋ฉ์๋ (equal, toString)๋ ์ธํฐํ์ด์ค์์ default๋ก ์ ์ ํ ์ ์๋ค. ์ฌ์ฉํ ๋ ค๋ฉด ๋ฐ๋์ ๊ตฌํ์ฒด๊ฐ ์ฌ์ ์ ๋์ด์ผ ํ๋ค.
public interface Foo {
void printName(); // ์ถ์๋ฉ์๋ 1
String getName(); // ์ถ์๋ฉ์๋ 2
String toString(); // Object ๋ฉ์๋๋ ์ถ์๋ฉ์๋๋ก ์ ์๋ ๊ฐ๋ฅ.
// default String toString(); // ์ปดํ์ผ ์๋ฌ!! default ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
}
# ์ธํฐํ์ด์ค ์์
์ธํฐํ์ด์ค๋ ์์ํด์ ์ฌ์ฉ ํ ์ ์๋ค. ๋ถ๋ชจ์์ Default๋ก ๊ตฌํ ๋์ด์๋ ๋ถ๋ถ์ ์ถ์๋ฉ์๋๋ก ๋ณ๊ฒฝํ ์๋ ์๋ค.
์ฐธ๊ณ ๋ก ์๋ฐ์์๋ ์ฌ๋ฌ ๊ฐ์ฒด๋ค์ ๋์์ ์์ ํ ์ ์๊ธฐ์ ๋ค์ค์์ ์ค๋ณต ๋ฌธ์ (Diamond Problem)๊ฐ ์๊ธดํ๋ฐ, ์ด ๊ฒฝ์ฐ ์ปดํ์ผ ์๋ฌ๊ฐ ๋จ๋ ์ง์ ํ๋ํ๋ @Override ํด์ฃผ๋ฉด ๋๋ค. ๋ค๋ง ์ค์ ๊ฐ๋ฐ์์ ์ด๋ฐ์์ ๋ค์ค ์์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๊ฑฐ์ ์๋ค.
public interface Foo {
String getName();
default void printName();{
System.out.println("Hello");
}
}
public interface Bar extends Foo{
void printName(); // Foo ์ default๋ฉ์๋๋ฅผ ์์ ์ฃผ์๋ค.
void newMethod();
}
# Java8์ ์ถ๊ฐ๋ ๊ธฐ๋ณธ ๋ฉ์๋, ์ธํฐํ์ด์ค
์์ ๊ฐ์ด ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ฌ์ฉํ๊ธฐ ์ข๊ฒ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํด์ค์ผ๋ก์ ์ฌ๋ฐ๋ ๋ฉ์๋๋ค์ด ๋ง์ด ์ถ๊ฐ๋์๋ค. ์ด ๊ธ์์๋ ๊ฐ๋จํ๊ฒ ์ดํด๋ง ๋ณด๊ณ ๋ค์ ๊ธ์ ์์ธํ ์ค๋ช ํ๋๋ก ํ๊ฒ ๋ค.
Iterable์ ๊ธฐ๋ณธ ๋ฉ์๋
- forEach()
- spliterator()
import java.util.Arrays;
import java.util.List;
import java.util.Spliterator;
public class Main {
public static void main(String[] args) {
List<String> name = Arrays.asList("Hi", "Bye", "Ho", "AB");
name.forEach(System.out::println); // ๊ฐ๊ฐ์ ์์๋ฅผ ์ถ๋ ฅ
// split + iterator. ํฐ ๋ฐฐ์ด์ ๋ฐ์ผ๋ก ๋๋ ๊ฐ๊ฐ iter๋ฅผ ๋๋ฆด ์ ์๋ค.
Spliterator<String> spliterator1 = name.spliterator();
Spliterator<String> spliterator2 = spliterator1.trySplit(); // ์๋์ผ๋ก ๋๋ ์ค๋ค.
while(spliterator1.tryAdvance(System.out::println)); // "Hi", "Bye"
while(spliterator2.tryAdvance(System.out::println)); // "Ho", "AB"
}
}
Collection์ ๊ธฐ๋ณธ ๋ฉ์๋
- stream() / parallelStream()
- removeIf(Predicate)
- spliterator()
public class Main {
public static void main(String[] args) {
List<String> name = Arrays.asList("KHi", "Bye", "KHo", "AB");
long nStartsWithK = name.stream().map(String::toUpperCase)
.filter(str -> str.startsWith("K"))
.count();
System.out.println(nStartsWithK); // 2
List<String> names = name.stream().map(String::toUpperCase)
.filter(str -> str.startsWith("K"))
.collect(Collectors.toList());
System.out.println(names); // ["KHi", "KHo"]
}
}
Comparator์ ๊ธฐ๋ณธ ๋ฉ์๋ ๋ฐ ์คํํฑ ๋ฉ์๋
- reversed()
- thenComparing()
- static reverseOrder() / naturalOrder()
- static nullsFirst() / nullsLast()
- static comparing()
+ Java9์ Private Method
์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๋ฉด์ ์ฌ์ฉ์ ํธํ๊ฒ ํ๊ธฐ์ํด Java8์ default ๋ฉ์๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์๋ค. ๊ทธ๋ฐ๋ฐ ์ฌ์ฉํ๋ค๋ณด๋ฉด default ๋ฉ์๋๊ฐ ๋จ์ํ ์ฌ์ฉ์ ํธํ๊ฒ ํ๊ธฐ์ํจ์ด ์๋๋ผ, ๊ณ ์ ๋ ๊ธฐ๋ณธ ๊ฐ์ ์ฃผ๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ๊ทธ๋ด ๋๋ฅผ ์ํด์ Java9๋ถํฐ private Method๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
Private ๋ฉ์๋๋ default ๋ฉ์๋์ ๋น์ทํ๋, ์ธํฐํ์ด์ค๋ฅผ ์์ ๋ฐ์์ ๋ด์ฉ์ ์์ ํ์ง ๋ชปํ๊ฒ ๋งํ์๋ค.
public interface Boo {
/**
* @implSpec ์ด ๋ฉ์๋๋ ์ค๋ฒ๋ผ์ด๋ ํ๊ฑฐ๋, ์ธ๋ถ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
* @return "Bye"
*/
private String printBye(){ // default์ ๋์ผํ ๊ธฐ๋ฅ. ํ์ง๋ง ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅ
return "Bye";
}
default void knockDoor(){
System.out.println("Ok.. " + printBye());
}
}
public class Main implements Boo{
@Override //Error -> method does not override or implement a method from a supertype
public String printBye(){
return "Bye";
}
}
'๐ฑBackend > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
#7 Exception (์์ธ์ฒ๋ฆฌ) (0) | 2021.07.07 |
---|---|
#6. Java - 2 ํด๋์ค (์์ฑ์์ ) (0) | 2021.07.07 |
#4. ์๋ฐ ํจ์ํ ์ธํฐํ์ด์ค (0) | 2021.07.01 |
#3. Java - 1 ๊ธฐ์ด๋ฌธ๋ฒ (0) | 2021.07.01 |
# 2. Java Naming Conventions (2) | 2021.06.30 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev