3장 자바와 객체지향
객체 지향은 현실 세계를 반영한다
- 객체 지향의 4대 특성
- 캡슐화(Encapsulation) - 정보 은닉
- 상속(
Inheritanceextends) - 재사용 - 추상화(Abstration) - 모델링
- 다형성 (Polymorphism) - 사용 편의
- 추상화
- 구체적인 것을 분해해서 관심 영역에 대한 특성만을 가지고 재조합 하는 것
- ex) 은행 -> 사람 : 고객, 병원 -> 사람 : 환자
- 사용
- 클래스 설계에서 사용
- 상속을 통한 추상화 및 구체화
- 인터페이스를 통한 추상화
- 다형성을 통한 추상화
- 구체적인 것을 분해해서 관심 영역에 대한 특성만을 가지고 재조합 하는 것
- 상속 : 재사용 + 확장
- 상위 클래스의 특성을 하위 클래스가 확장하는 것
- 상속 관계에서 만족해야할 것
- "하위 클래스는 상위 클래스다"
- 상속은 "is a kind of" 관계 : 하위 클래스 is a kind of 상위 클래스
- 다중 상속의 다이아몬드 문제
- 인어 공주 : 물고기, 사람을 모두 상속 받는 개념. 한 메서드를 호출했을 때 둘 중 어느 메서드를 택해야할지
- 인터페이스 "be able to" 관계 : '할 수 있다' 라는 기능을 구현하도록 강제하게 됨
- 상위 클래스는 특성이 풍성할수록(LSP 원칙) , 인터페이스는 구현을 강제할 메서드의 개수가 적을 수록 좋음(ISP 원칙)
- 상속의 메모리 구조
- 하위 클래스의 인스턴스가 생성될 때 상위 클래스의 인스턴스도 함께 생성됨
Penguin pororo = new Penguin();
Animal pingu = new Penguin(); // 펭귄 클래스에 단독 정의된 메서드 사용 불가
// Penguin 클래스의 객체를 갖지만 Animal로 참조되었으므로, 형변환이 없으면 사용 불가
- 다형성 : 사용 편의성
- 하나의 객체가 여러 가지 타입을 가질 수 있는 성질. 다형성을 통해 상위 클래스나 인터페이스를 기반으로 다양한 하위 클래스의 객체를 동일한 방식으로 처리 가능
- 상위 클래스 타입의 객체 참조 변수를 사용하더라도 하위 클래스에서 오버라이딩한 메서드가 호출됨
- 오버라이딩한 메소드를 자동으로 호출해줌으로서 간결한 코드 작성 가능
- 오버라이딩 : 같은 메서드 이름, 같은 인자 목록으로 상위 클래스의 메서드를 재정의
- 오버로딩 : 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 중복 정의
동물[] 동물들 = new 동물[5];
동물들[0] = new 쥐();
동물들[1] = new 고양이();
동물들[2] = new 강아지();
for(int i = 0; i < 3; i++) {
동물들[i].울어보세요();
}
/*
* 찍찍
* 야옹
* 멍멍
*/
- 캡슐화 : 정보 은닉
- 접근 제어자
- public : 모두가 접근 가능
- protected : 상속 / 같은 패키지 내의 클래스에서 접근 가능
- [default] : 같은 패키지 내
- private : 같은 클래스 내
- 하위 클래스에서는 상위 클래스보다 더 넓은 범위의 메서드만 작성 가능
- 접근 제어자
4장 자바가 확장한 객체 지향
- abstract 키워드 - 추상 메서드와 추상 클래스
- 선언부는 있는데 구현부가 없는 메서드
- 하위 클래스에게 메서드의 구현을 강제(오버라이딩 강제)
- 추상 클래스 : 인스턴스 생성 불가
- 목적
- 상속으로 구현하게 되면 상위 클래스의 기본 메서드에 구현을 하는 것이 어색할 때가 있음 (동물 클래스의 '울어보세요'는 어떻게 구현해야할지)
- 하위 클래스에서 모두 동일한 메서드를 호출하고자 할 때 메서드의 구현을 강제할 필요가 있음
- 목적
- 추상 메서드를 포함하는 클래스는 반드시 추상 클래스여야함
- interface 키워드
- 추상 메서드와 public 정적 상수만 가질 수 있음
- 자바 8 이후에는 람다 도입을 위해 객체 구현 메서드 - 디폴트 메서드 , 정적 추상(static abstract) 메서드지원
- 추상 메서드와 public 정적 상수만 가질 수 있음
interface Speakable {
public static final double PO = 3.14159; // static final 자바에서 자동 주입(생략 가능)
public abstract void sayYes(); // abstract 자바에서 자동 주입(생략 가능)
}
- 자바 구성 요소
- 패키지 : 네임스페이스
- 클래스 : 분류, 같은 속성과 기능을 가진 객체를 총칭하는 개념
- 객체 : 실체, 세상에 존재하는 유일무이한 사물
- 메서드 : 기능 / 행위
5장 객체 지향 설계 5원칙 - SOLID
- SRP (Single Responsebility Principle) : 단일 책임 원칙
- OCP (Open Closed Principle) : 개방 폐쇄 원칙
- LSP (Liskov Substitution Principle) : 리스코프 치환 원칙
- ISP (Interface Segregation Principle) : 인터페이스 분리 원칙
- DIP (Dependency Inversion Principle) : 의존성 역전 원칙
- 결합도와 응집도
- 좋은 소프트웨어 설계 : 낮은 결합도, 높은 응집도
- 결합도 : 모듈(클래스)간의 상호 의존 정도. 낮을수록 객체의 재사용이나 수정, 유지보수가 용이
- 응집도 : 하나의 모듈 내부에 존재하는 구성 요소들의 기능적 관련성. 높을수록 하나의 책임에 집중하고 독립성이 높아져 재사용이나 유지보수가 용이
- SRP (Single Responsebility Principle) : 단일 책임 원칙
- "어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이여야 한다"
- 위배 사례
- 하나의 클래스에서 사용하지 않는 여러 메서드가 구현되는 경우
- 하나의 속성이 여러 의미를 갖는 경우 (if문이 잦음)
- 위배하게 된다면 다른 곳에서 해당 객체의 특성을 변경 가능하다는 위험이 있음
- OCP (Open Closed Principle) : 개방 폐쇄 원칙
- "소프트웨어 엔티티(클래스, 모듈, 함수 등)은 확장에 대해서는 열려 있어야 하지만 변경에 대해서는 닫혀 있어야 함
- 위배 사례
- 다른 차를 상속받게 될 때 '자동 개방'같은 함수로 인해 차종을 바꾸니 운전자의 행동에도 변화가 오게 됨 (메서드 호출시에 함수를 바꿔야함)
- -> 상위 클래스 또는 인터페이스를 중간에 둠으로써 운전자의 행동에 변화를 가지지 않아도 됨
- 위배하게 된다면 유연성, 재사용성, 유지 보수성을 얻을 수 없음
![]() |
![]() |
- LSP (Liskov Substitution Principle) : 리스코프 치환 원칙
- "서브 타입은 언제나 자신의 기반타입(base type)으로 교체할 수 있어야 한다"
- 아래 두 규칙을 만족한다면 리스코프 치환 원칙을 잘 지키는 것
- 하위 클래스 is a kind of 상위 클래스 - 하위 분류는 상위 분류의 한 종류
- 구현 클래스 is able to 인터페이스 - 구현 분류는 인터페이스할 수 있어야 함
- 하위 클래스의 인스턴스는 상위형 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 하는데 문제가 없음
Animal penguin = new Penguin();
// Animal 의 행동을 수행하는데 문제가 없어야 함
- ISP (Interface Segregation Principle) : 인터페이스 분리 원칙
- "클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안된다"
- SRP와 ISP는 같은 문제에 대한 두 가지 해결책
- 각 역할에 맞는 인터페이스를 생성하여 이를 한 클래스에서 구현
- 인터페이스 최소주의 원칙
- 인터페이스를 통해 메서드를 외부에 제공할 때는 최소한의 메서드만 제공
- 그렇게 해야 각 책임에 대한 행동만을 수행할 수 있음
- 특별한 경우가 아니라면 단일 책임 원칙을 제공하는게 더 좋은 해결책
![]() 분리되지 않은 클래스 |
![]() 단일 책임 원칙으로 재구현한 사례 |
![]() 인터페이스 분리 원칙으로 재구현한 사례 |
- DIP (Dependency Inversion Principle) : 의존성 역전 원칙
- "고차원 모듈은 저차원 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야한다. 추상화된 것은 구체적인 것에 의존하면 안된다."
- 구체적인 것에 의존하게 된다면 구현체가 바뀔때 마다 수정이 필요하게 됨 (OCP 위배)
- -> 이를 위해 중간에 추상화된 인터페이스를 추가해 의존 관계를 역전 시키고 있음
- "자기보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변화기 쉬운 것의 변화에 영향받지 않게 하는 것" = 의존 역전 원칙
'BOOK Review' 카테고리의 다른 글
[스프링입문을위한 자바 객체지향의 원리와 이해] 6장 ~ 7장 스프링 (4) | 2024.09.14 |
---|---|
[스프링입문을위한 자바 객체지향의 원리와 이해] 1장 ~ 2장 (1) | 2024.09.11 |
[클린코드] Final Review (0) | 2024.07.11 |
[클린코드] TIL - 10장 클래스 (0) | 2024.07.08 |
[클린코드] TIL - 9장 단위 테스트 (1) | 2024.07.05 |