Open callmeaxxe opened 1 year ago
// 코드 20-1 골격 구현을 사용해 완성한 구체 클래스 (133쪽)
public class IntArrays {
static List<Integer> intArrayAsList(int[] a) {
Objects.requireNonNull(a);
// 다이아몬드 연산자를 이렇게 사용하는 건 자바 9부터 가능하다.
// 더 낮은 버전을 사용한다면 <Integer>로 수정하자.
return new AbstractList<>() {
@Override public Integer get(int i) {
return a[i]; // 오토박싱(아이템 6)
}
@Override public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // 오토언박싱
return oldVal; // 오토박싱
}
@Override public int size() {
return a.length;
}
};
}
public static void main(String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = i;
List<Integer> list = intArrayAsList(a);
Collections.shuffle(list);
System.out.println(list);
}
}
List
를 전체 구현해야한다면 많은 메서드를 직접 다 구현해줘야 한다AbstractList
를 사용해서 @Override
로 원하는 메서드만 재정의할 수 있다public class MyCat extends AbstractCat implements Flyable {
private MyFlyable myFlyable = new MyFlyable();
@Override
protected String sound() {
return "인싸 고양이 두 마리가 나가신다!";
}
@Override
protected String name() {
return "유미";
}
public static void main(String[] args) {
MyCat myCat = new MyCat();
System.out.println(myCat.sound());
System.out.println(myCat.name());
myCat.fly();
}
@Override
public void fly() {
this.myFlyable.fly();
}
private class MyFlyable extends AbstractFlyable {
@Override
public void fly() {
System.out.println("날아라.");
}
}
}
알고리듬 구조를 서브 클래스가 확장할 수 있도록 템플릿으로 제공하는 방법.
public abstract class FileProcessor {
private String path;
public FileProcessor(String path) {
this.path = path;
}
public final int process() {
try(BufferedReader reader = new BufferedReader(new FileReader(path))) {
int result = 0;
String line = null;
while((line = reader.readLine()) != null) {
result = getResult(result, Integer.parseInt(line));
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
protected abstract int getResult(int result, int number);
}
getResult
메서드를 추상으로 제공public class Client {
public static void main(String[] args) {
FileProcessor fileProcessor = new Plus("number.txt");
System.out.println(fileProcessor.process());
}
public static class Plus extends FileProcessor {
public Plus(String path) {
super(path);
}
@Override
protected int getResult(int result, int number) {
return result + number;
}
}
}
public class FileProcessor {
private String path;
public FileProcessor(String path) {
this.path = path;
}
public final int process(BiFunction<Integer, Integer, Integer> operation) {
try(BufferedReader reader = new BufferedReader(new FileReader(path))) {
int result = 0;
String line = null;
while((line = reader.readLine()) != null) {
result = operation.apply(result, Integer.valueOf(line));
}
return result;
} catch (IOException e) {
throw new IllegalArgumentException(path + "에 해당하는 파일이 없습니다.", e);
}
}
// protected abstract int getResult(int result, int number);
}
public class Client {
public static void main(String[] args) {
FileProcessor fileProcessor = new FileProcessor("number.txt");
System.out.println(fileProcessor.process((a, b) -> a + b));
}
}
인터페이스의 디폴트 메서드로 Object 메서드(toString
, hashCode
, equals
)를 재정의 할 수 없는 이유
아이템 20. 추상 클래스보다 인터페이스를 우선하라.
핵심 정리: 인터페이스의 장점
보통 인터페이스는 타입을 정의할 때, 추상 클래스는 인터페이스의 기능을 일부 제공할 때 사용한다 추상 클래스를 상속받는 형식으로 사용하기보단, 인터페이스 구현의 방식을 우선 고려하라는 것
인터페이스 - default method
인터페이스 - 믹스인(mixtin)
인터페이스 - 계층구조가 없는 타입 프레임워크
Singer
,SongWriter
클래스가 존재할 때, 둘 사이에는 계층구조가 존재하지 않다. (가수와 작곡가 누구도 더 윗사람인 관계가 아니다)implements Singer, SongWriter
로 적용할 수 있다는 것인터페이스 - 래퍼 클래스와 함께 사용할 때