#5. μλ°μ Interface
# 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";
}
}