![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/5PI1r/btrv45KOjx5/jxE2ssqB1qHklsShnhUKUK/img.png)
디폴트 메서드의 도입 - 자바8부터는 기존 인터페이스에 메서드를 추가할 수 있도록 디폴트 메서드를 도입. but 디폴트 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 되므로 모든 기존 구현체들과 매끄럽게 연동되리라는 보장을 할 수 없음 - 자바8에서는 핵심 컬렉션 인터페이스들에 다수의 디폴트 메서드가 추가됨 → 람다 활용 위해 추가된 메서드들은 품질이 높고 범용적이어서 대부분 상황에서 잘 작동 but 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하긴 어렵다. default boolean removeIf(Predicate
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/xc5zh/btrwb5vL35B/fTKKBK42AeX71jKrogqAeK/img.png)
자바가 제공하는 다중 구현 메커니즘 : 인터페이스, 추상 클래스 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상클래스의 하위 클래스가 되어야 한다. 자바는 단일 상속을 지원하기 때문에 추상 클래스 방식은 새로운 타입을 정의하는데 제약 but 인터페이스를 구현한 클래스는 다른 어떤 클래스를 상속했든 간에 같은 타입으로 취급 인터페이스 기존 클래스에도 손쉽게 새로운 인터페이스를 구현해넣을 수 있다.but 추상 클래스는 그렇지 않다. 새로 추가된 추상 클래스의 모든 자손이 상속구조를 가지게 되며 혼란을 줌. 인터페이스가 요구하는 메서드를 추가하고 implements 구문만 추가하면 된다. 인터페이스는 믹스인에 적절함 : 원래의 주된 타입 외에 특정 선택적 행위를 제공 효과 but 추상 클래스는 그렇..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/bguxNS/btrwapnTXMw/hdDXyQMVi8i9s1HYD8JEPK/img.png)
상속을 고려한 설계와 문서화 1) 메서드를 재정의할때 어떤일이 일어나는지 정확히 정리하여 문서로 남겨라. 상속용 클래스는 재정의할 수 있는 메서드(public, protected 이면서 final이 아닌 메서드)들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다. 2) 효율적인 하위 클래스를 어려움 없이 만들 수 있게 하기 위해 클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅을 잘 선별하여 protected 메서드 형태로 공개해야 할 수도 있다. 3) 상속용으로 설계한 클래스를 시험하는 방법은 직접 하위 클래스를 만들어보는 것이다. 꼭 필요한 protected 멤버를 놓쳤다면 빈 자리가 드러남, 전혀 쓰이지 않는 protected 멤버는 사실 private 임 등을 알 수 있다. 배포전에 반드시 하..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/AeaOE/btrvLJ2mchQ/i0oHN7wtt79mAjIoAERTU0/img.png)
상속은 코드를 재사용하는 강력한 수단이나 항상 최선은 아니다. 다른 패키지의 구체 클래스를 상속하는 일은 위험하다. 캡슐화를 깨뜨리는 상속 상위 클래스가 어떻게 구현되느냐에 따라 하위 클래스의 동작에 이상이 생길 수 있음 설계자가 확장을 충분히 고려하지 않으면, 하위 클래스는 상위 클래스 변화에 맞춰 수정되어야만 한다. public class InstrumentedHashSet extends HashSet { private int addCount = 0; public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } @Override public boolean add(E e) { addCount++; ret..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/coKSXR/btrvLJnKeCN/cTxmBVJu90i0X9RRjIvp31/img.png)
불변 클래스 그 인스턴스의 내부 값을 수정할 수 없는 클래스 ex)String, 기본 타입 박싱 클래스들, BigInteger, BigDecimal 가변 클래스보다 설계/구현/사용이 쉬움, 오류가 더 적음 불변 클래스를 만들기 위한 규칙 객체의 상태를 변경하는 메서드를 제공하지 않음 클래스를 확장할 수 없음 (하위 클래스에서 객체의 상태를 변하게 만드는 사태를 막기 위함) 모든 필드를 final로 선언 : 여러 스레드에서 접근해도 값이 바뀌지 않음 모든 필드를 private 으로 선언 : 직접 접근해서 수정하지 못하도록 함 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 함 가변 객체를 참조하는 필드가 있다면 클라이언트가 접근하지 못하도록 해야함 접근자 메서드로 반환해서도 안됨. 생성자, 접근자, ..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/1URGk/btrvOhw3bZy/eQxx5WPOAJGU3rrvcEb3zK/img.png)
인스턴스 필드들을 모아놓는 일 외에는 목적없는 클래스를 작성할 때가 있다. class Point { public double x; public double y; } 이런 클래스는 데이터 필드에 직접 접근이 가능하기 때문에 캡슐화의 이점을 제공하지 못한다. API를 수정하지 않고는 내부 표현 수정 불가, 불변식 보장 x, 스레드 안전하지 않음 → 필드를 private으로 바꾸고 getter 메서드를 제공한다. 하지만 package-private 클래스나 private 중첩 클래스라면 데이터 필드를 노출해도 하등의 문제가 없다. (getter 방식보다 깔끔) class Point { private double x; private double y; public Point(double x, double y) {..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/bokiso/btrvNIuS378/v14hRAVnMBgU6lrGmg4k40/img.png)
잘 설계된 컴포넌트 → 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨긴 컴포넌트 (구현과 API를 깔끔하게 분리) API를 통해서만 다른 컴포넌트와 소통하고 서로의 내부 동작 방식에는 참견하지 않음 정보 은닉과 캡슐화는 소프트웨어 설계의 근간이 되는 원리 정보 은닉 시스템 개발 속도를 높임 (여러 컴포넌트를 병렬로 개발할 수 있어서) 시스템 관리 비용을 낮춤. 컴포넌트를 빠르게 파악하여 디버깅이 가능하고, 다른 컴포넌트로 교체하는 부담도 적기 때문 최적화활 컴포넌트를 정한 다음, 다른 컴포넌트에 영향을 주지 않고 그것만 최적화 할 수 있어서 성능 최적화에 도움을 줌 소프트웨어 재사용성을 높임. 외부에 의존하지 않고 독자적으로 동작하는 컴포넌트는 다른 낯선 환경에서도 유용하게 쓰일 수 ..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/tq5m5/btrvMcP0Hi3/dAvlrVHZikQy5ZF0XlnqK0/img.png)
Comparable 인터페이스의 compareTo compareTo()는 Object의 equals()와 다르게 단순 동치성 비교 뿐만 아니라 순서 비교도 가능하며 제네릭함 Comparable을 구현 → 인스턴스들에 자연적인 순서가 있음 → 손쉽게 정렬 가능 Arrays.sort(a); , 컬렉션 검색/극단값 계산/자동 정렬 비교를 활용하는 정렬된 컬렉션인 TreeSet과 TreeMap이 있고, 검색과 정렬 알고리즘을 활용하는 유틸리티 클래스인 Collections와 Arrays가 있음 규약 순서를 비교할 때 이 객체가 주어진 객체보다 작으면 음의정수(-1), 같으면 (0), 크면 양의정수(+1) 반환 비교할 수 없는 타입의 객체가 주어지면 ClassCastException 을 던짐 1) x.compar..