자바 기초 스터디_22.02.04(목)
public interface Foo {
void printName();
}
public class DefaultFoo implements Foo {
@Override
public void printName() {
System.out.println("DefaultFoo")
}
}
Foo 인터페이스에 새로운 기능이 추가가 필요할때 위 상태에서 그냥 추가해버리면
DefaultFoo 클래스에서 구현해주지 않았으므로 컴파일 에러가 난다.
🔻 이럴때 default 메소드를 활용해주면된다.
public interface Foo {
void printName();
default void printNameUpperCase() {
System.out.println(getName().toUpperCase());
}
String getName();
}
public class DefaultFoo implements Foo {
String name;
public DefaultFoo(String name) {
this.name = name;
}
@Override
public void printName() {
System.out.println(this.name)
}
@Override
public void getName() {
return this.name;
}
}
하지만, 안정적인 코드는 아니다 getName에 null이 들어와서 런타임 에러가 발생할 수 있는것처럼
어떤 값이 들어올지 모르니, 🔻 최소한의 문서화작업(@implSpec)이 필요하다.
public interface Foo {
void printName();
/**
* @implSpec
* 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
*/
default void printNameUpperCase() {
System.out.println(getName().toUpperCase());
}
String getName();
}
🔻 아니면, 구현하는 곳에서 구현체를 재정의해서 문제되는 부분을 해결할 수 있다.
public class DefaultFoo implements Foo {
String name;
public DefaultFoo(String name) {
this.name = name;
}
@Override
public void printNameUpperCase() {
System.out.println(this.name.toUpperCase()) //구현체 재정의
}
@Override
public void printName() {
System.out.println(this.name)
}
@Override
public void getName() {
return this.name;
}
}
🔻 제약사항으로는, Object에 있는것들은 재정의 할 수가 없다. 선언은 가능
public interface Foo {
default String toString(){ // X Object에 있는것들은 재정의 할 수 없다.
}
String toString(); // 선언은 가능
}
public interface Foo {
void printName();
/**
* @implSpec
* 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
*/
default void printNameUpperCase() {
System.out.println(getName().toUpperCase());
}
static void printAnything() {
System.out.println("Foo"); // Foo타입 가지고 참조해서 Foo.printAnything(); 으로 쓸 수 있다.
}
String getName();
}