Ch05. 객체지향의 이해
객체지향 프로그램(OOP: Object - Oriented Programming)
- 객체지향 프로그래밍은 상속, 다형성, 추상화, 캡슐화 등 많은 개념을 제공하며 클래스 및 객체를 사용하여 프로그램을 설계하는 방법론이며 패러다임이다
- 객체지향의 역사
- 1960년대 최초의 객체지향언어 Simula탄생
- 1980년대 절차방식의 프로그래밍의 한계를 객체지향으로 극복하려고 노력함 C++, Smalltak 탄생
- 1995년 Java가 탄생하였고, 객체지향 언어의 주류가 됨
- OOAD Object-Oriented Analysis and Design 객체지향 설계을 위한 모델링 기법
- 현실세계의 행동과 활동, 객체 그리고 행동,습성을 모델링
- 시스템내에 객체와 행동사이의 관계와 상호작용을 모델링
- OOP 사용 목적
- 코드의 재사용성 Reuse 을 극대화 : 새로운 코드를 작성할 때 기존 코드를 이용해서 쉽고 빠르게 작성 할 수 있다
- 특정 모듈의 기능 변경이 다른 모듈에 영향을 미치지 않는다
- Object 객체 란?
- 현실세계에 존재하는 모든 것. 사물 또는 개념 예 : 의자, 자전거, 자동차
객체지향 프로그래밍
- 객체지향의 요소
- Class : 같은 종류의 집단에 속하는 속성 attribute 과 행위 behavior 에 대한 정의, 객체를 만들기 위한 설계도, 설명
- Object : 클래스의 인스턴스 실제 메모리 할당, Runtime Entity , 자신의 고유의 데이터 attribute 를 갖고 행위 behavior 를 수행
- Attribute, Method, Constructor 생성자 , Package 등등
- 특징
- 상속 inheritance : 하나의 클래스와 상속관계를 통해 상위클래스의 필드 field 와 메서드 method 획득하여 상위 클래스의 필드,메서드 재사용
- 다형성 polymorphism : 상황에 따라 메서드의 성질을 변화시키는 것
- 상속 관계에서 동물 부모 -> 고양이, 개, 코끼리 자식 클래스 말하기 메서드의 메서드 오버라이딩으로 각 객체의 특성에 맞게 구현되어 행동하게 하는 것
- 추상화 abstraction : 객체들이 가진 공통 특성을 파악하고 불필요한 특성을 제거하는 과정으로 단순화하여 세부정보를 숨기고 기능을 표시하는 것
- 예 : TV 리모컨 -> 내부처리를 모른다 추상클래스와 인터페이스
- 캡슐화 encapsulation : 하나의 문제해결을 위한 데이터와 메서드의 묶음. 내부 정의를 외부에 보이지 않도록 하기 위해 외부 접근을 차단한다
- 외부 접근을 차단하여 데이터의 외부 간섭 및 오용으로부터 보호하는데 이를 정보 은닉 information hiding 이라고한다
- 목적은 높은 응집력 High Cohesion 과 약한 결합 Weak Coupling 이다
- OOP는 개발 및 유지 관리를 쉽게 해주는 반면 절차 지향 프로그래밍 언어에서는 프로젝트 크기가 증가함에 따라 코드가 커지면 관리하기가 쉽지 않다
- OOP는 데이터 숨김을 제공하는 반면 프로시저 지향 프로그래밍 언어에서는 전역 데이터에 어디서나 액세스 할 수 있다
- 절차보다는 데이터에 중점을 두며, 프로그램을 객체로 나눈다
클래스와 객체
- 클래스 Class 와 객체 Object 의 관계
- 클래스로 모델링한 객체를 정의한다
- 객체를 생성할 수 있는 틀을 제공해 주는 소스코드
- House Blueprint 청사진 , Template, 붕어빵 틀
- Java의 클래스는 다음이 포함될 수 있다
- Fields, 메소드, 생성자, 블럭, 중첩 클래스 및 인터페이스
- 객체는 클래스의 인스턴스 하나의 예 다
- 객체는 메모리 공간의 위치정보 주소 를 포함하고 있다
- 클래스는 ‘데이터 타입’, 객체는 해당 타입의 ‘변수’ = 클래스를 통해 원하는대로 객체를 생성할 수 있다
- Shirt shirt = new Shirt ;
- 클래스 Class 와 객체 Object 의 관계
- 객체간에는 서로의 세부정보를 알지 못해도 허용된 메시지 전송과 값의 전달을 통해 통신할 수 있다
객체지향 프로그래밍
- 도식화
- 객체 지향 설계의 5대 원칙 SOLID : 소프트웨어 구조 설계에 적용되는 객체 지향 접근 방식으로 이 다섯 가지 원칙은 객체 지향 프로그래밍의 세계를 변화시켰고 소프트웨어 작성 방식도 변화시켰다
- SRP Single Responsibility Principle : 단일 책임 원칙
- 모든 클래스는 각각 하나의 책임만 가지고 단일 기능을 수행해야 한다
- 단일 클래스에서 여러 기능을 구현하면 코드가 매시업되고 수정이 필요한 경우 전체 클래스에 영향을 미칠 수 있다
- 코드가 정확하고 코드를 쉽게 유지 관리할 수 있다
- OCP Open Closed Principle : 개방-폐쇄 원칙
- 기존의 코드를 변경하지 않으면서 closed , 기능을 추가할 수 있도록 open 설계가 되어야 한다
- 확장을 통해 모듈에 새로운 기능을 구현할 수 있다
- LSP Liscov Substitution Principle : 리스코프 치환 원칙
- 자식 클래스는 언제나 부모 클래스를 대체하여 동작하는데 문제가 없어야 한다 다형성 원리
- 자바 컬렉션 프레임워크 JFC 가 대표적으로 잘 적용한 예이다
- ISP Interface Segregation Principle : 인터페이스 분리 원칙
- 한 클래스는 자신이 사용하지 않는 인터페이스를 구현하지 말아야 한다
- 하나의 일반적인 인터페이스보다 여러 개의 구체적인 인터페이스로 분할하는게 맞다
- DIP Dependency Inversion Principle : 의존성 역전 원칙
- 의존 관계를 구체적인 구현 클래스 대신 추상화된 추상클래스나 인터페이스에 의존해야 하며, 고수준 모듈에서 저수준 모듈에 의존해서는 안된다
- SRP Single Responsibility Principle : 단일 책임 원칙
- SOLID 원칙 사용 이유
- 다른 코드 블록에 영향을 주지 않고 코드 블록을 변경할 수 있도록 종속성을 줄일 수 있다
- 디자인을 더 쉽고 이해하기 쉽게 만들기 위한 원칙이다
- 이 원칙을 사용하면 시스템을 유지 관리, 테스트, 확장 및 재사용할 수 있다
- 소프트웨어의 bad design을 피할 수 있다
클래스(class) 선언 및 작성
- Object-Oriented design된 class를 작성한다
- class에 class name, variable과 method를 정의한다
- class file 저장시 class name앞에 public modifier를 붙인 class name으로 지정한 이름으로 저장되어야 하며 저장시 클래스명.java로 저장해야 한
- public class Order -> Order.java
- public modifier을 붙이지 않고도 저장할 수는 있다
- Class는 대문자로 시작해야 한다
더보기
[Class Syntax]
<modifier>* class <class_name> {
<attribute_declaration>*
<constructor_declaration>*
<method_declaration>*
}
예제)
public class Order {
private int orderId;
public void setOrder(int orderId) {
this.orderId = orderId;
}
}
클래스 구성요소
- 클래스의 구성요소는 아래와 같다
- 필드 변수, 상수
- 메서드 Method
- 생성자 Constructor
- 초기화 블록 생성자 호출 전 필드 초기화
- 내부 클래스
public class Account {
static String bankName; // 클래스 변수
long accountNO; // 인스턴스 변수
String customerName; // 인스턴스 변수
// 생성자
Account (){
System.out.println("셍상자 실행");
}
// 초기화 블럭
{
System.out.println("블록입니다");
}
// 메서드
void printInfo(){
System.out.println ("계좌 클래스");
}
}
Software Package
- Package는 클래스들의 묶음이며 각 클래스 구분을 위한 Namespace의 역할을 한다
- 패키지 내부의 패키지를 하위 패키지 라고 한다. 패키지를 추가로 분류하기 위해 생성되 어야 하며, 패키지를 통해 동일한 클래스명의 충돌을 제거할 수 있다
- 기본 문법
- package <top package name>[.<sub package name>];
- package company.order;
- Package에 속한 클래스를 컴파일 할 때는 -d option을 사용한다
- 기본 문법 IDE를 이용할 경우 필요 없으나 command line에 컴파일시 참고
- Java프로젝트폴더의source경로로이동 cd Java 프로젝트 폴더/src
- 패키지를 선언한 java 소스 컴파일 :
- javac -d <class 파일생성경로> <컴파일 대상 java소스>
- 예 javac -d ../out/production/EduExample ch05/TestStudent.java
import 문
- import는 클래스 또는 패키지명까지 작성하여 사용하고자 하는 클래스나 API를 정의 한다
- import를 통해 third party로 제공되는 라이브러리나 다른 개발자가 개발한 패키지의 클래스를 사용할 수 있다
- 기본 문법
import <package name>[.<sub package name>]*.<class name>
import <package name>[.<sub package name>]*.*;
예) import java.util.List; <- 클래스명까지해서 풀네임을 사용
import java.io.*; <- java.io 패키지내에 모든 클래스를 import하고 싶을 때 사용
제어자(modifier)
- 클래스, 변수, 메소드의 선언부에 사용되며 부가적인 의미를 부여한다
- 제어자는 크게 접근 제어와 그 외 제어자로 나뉘며, 하나의 대상에 여러 개의 제어를 조합해서 사용할 수 있으나, 접근 제어자 Access modifier 는 단 하나만 사용할 수 있다
- 접근 제어자 : public, protected, default, private
- 그 외 : static, final, abstract, native, transient, synchronized, volatile, strictfp
접근제어자(Access modifier)
- 접근 제어자는 클래스, 변수, 메소드, 생성자 들의 접근을 제어하는 용도로 사용한다
- 캡슐화 및 재사용성을 보장하기 위해 액세스 지정자는 OOP의 필수적 부분 이다
- 접근 범위는 public > protected > default > private 순이다
- 접근제어자 유형
- public : 제한없이 접근 할 수 있다
- protected : 같은 패키지내 또는 상속 관계 범위에서 접근 할 수 있다
- default : 접근제어자 지정을 안할 경우 default 접근제어자이다
- private : 지정되면 클래스내에서만 접근할 수 있으며, 생성자를 private으로 지정하면 상속이 불가하다