Leeyebin의 블로그
[JAVA] 객체지향 본문
객체지향 프로그래밍(OOP : Object-Oriented Programming)
- 객체 지향 프로그래밍은 컴퓨터 프로그래밍의 패러다임의 하나이다.
- 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, '객체'들의 모임으로 파악하고자 하는 것이다.
- 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다.
출처 : 위키피디아
객체란?
- 실세계와 비교하자면 세상에 존재하는 모든 사물이 객체
- 저장 공간에 할당된 공간(객체 참조 변수를 통해 해당 공간에 접근)
- 하나의 클래스를 통해 다수의 객체가 생성되지만 각각의 객체는 공유함
- 속성 + 행위
클래스란?
- 같은 속성들과 기능들을 가진 객체들을 총칭하는 개념
- (이 개념적인 클래스를 통해 실체화 된 것이 객체(인스턴스))
- 객체는 필드와 메소드를 가진다.
- (클래스를 통해 실체화된 객체는 필드를 통해 고유한 속성을 가지고 메소드로 행위를 한다.
- 클래스 객체참조변수명 = new 클래스(); //new 연산자를 통해 객체가 메모리에 할당되고 해당 객체의 생성자가 호출된다.
클래스 구성 멤버
public class 자동차 { String 이름; //필드 public 자동차(){ //생성자 } public void 시동켜기(){ //메소드 } }
필드(Field)
- 라이프 사이클
- 필드는 객체 소멸 시 함께 소멸
- 변수는 생성자 또는 메서드 수행이 종료되면 소멸
- 초기화
- 필드 선언 시
- 필드의 초기 값이 모든 객체에 대해 동일한 경우
- 생성자에서
- 객체 생성 시점이 외부의 값으로 대입이 필요한 경우
생성자
- new 연산자로 호출되며, 객체 생성 시 초기화를 담당.
- 클래스 이름으로 되어 있고 리턴타입이 없다.
- 명시하지 않으면 JVM이 기본 생성자 생성(인자가 있는 생성자를 만들면 생성자가 있다고 JVM이 판단해서 기본생성자를 따로 만들지 않아준다.)
- 상속 관계에서 객체 생성은 상위클래스가 먼저 초기화 되고, 하위 클래스가 초기화 된다.
메소드(Method)
- 객체의 동작에 해당하며 해당 객체의 필드를 읽고 수정하는 역할과 객체간의 상호작용 역할
- 외부로부터 값을 받을 수도 있고 실행 후 외부로 값을 반환 할 수도 있다.
- 선언부와 실행 블록으로 구성
- 선언부를 시그니처라고도 한다.(반환타입, 메소드명, 매개변수)
객체 vs 클래스
- 클래스는 메소드 영역에 생성
- 객체는 힙 영역에 생성
- 객체의 메소드가 수행되면 스택 프레임이 생성
- 메소드 내의 지역변수들은 스택프레임의 스택에 쌓임
추후에 추가할 것
객체간의 관계
사람 ---사용관계--->자동차---상속관계--->기계
자동차<---집합 관계---엔진,타이어,핸들
- 집합관계
- 하나는 완성품, 하나는 부품
- 사용 관계
- 객체 간의 상호 작용
- 하나의 객체가 다른 객체의 메소드를 호출하여 원하는 결과를 얻어냄
- 상속 관계
- 상위 객체를 기반으로 하위 객체를 생성하는 관계
- 상위 객체는 종류/분류. 하위 객체는 구체적인 사물에 해당
객체지향의 4대 특성
*캡슐화(Encapsulation)
- 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 함(정보은닉)
- 변화에 유연한 대응
- 필드에 해당되는 건 최대한 감춰라.
- 메소드만 접근하도록(너는 이것만 사용해)
Getter / Setter
- 객체의 데이터를 외부에서 마음대로 읽고 변경할 경우 객체의 무결성이 깨어질 수 있기 때문에 외부에서 직접적으로 접근하는 것을 막는다.
- 데이터는 외부에서 접근할 수 없도록 막고 메소드는 공개해서 외부에서 메소드를 통해 데이터에 접근하도록 유도
- 필드 타입이 boolean일 경우 is로 시작하는 것이 관례
*상속(inheritance)
- 상속의 목적은 재사용과 확장(자바에서의 상속에 해당하는 키워드는 extends)
- 상위 객체를 재사용해서 하위 객체를 쉽고 빨리 설계할 수 있도록 도와준다.
- 이미 잘 개발된 객체를 재사용해서 새로운 객체를 만들기 때문에 중복 코드를 줄여준다.
- 상속에는 is a 관계가 성립한다. (고양이는 포유류다. 말은 포유류다. 등)
- 하위클래스는 상위클래스이다.(LSP - 리스코프 치환 원칙 / SOLID의 L에 해당된다.)
- 상속에서의 메모리(하위 클래스를 생성하면 메모리에 상위클래스도 함께 적재된다.
- 자바에서는 다중 상속을 지원하지 않는다.(다이아몬드 상속 문제) - 이 문제를 해결하기 위해 인터페이스를 제공한다.(추상메소드)
- 인터페이스(interface)
- 다중 상속 가능
- 인터페이스의 메소드들은 전부 추상 메소드
- 모든 메소드는 기본적으로 public 접근 제한
- 하위 클래스에서는 implements 키워드를 사용하여 인터페이스를 구현
- 이반 클래스처럼 new 키워드로 생성될 수 없음
- 인터페이스들끼리의 상속 가능
- 인터페이스도 결국에는 컴파일러를 통해 .class 파일로 생성되기 때문에 물리적인 형태는 클래스와 동일
- 인터페이스는 무조건 구현해야한다.
- 인터페이스 구성 요소
- 상수 필드(Constant Field)
- 추상 메소드(Abstract Method)
- 인터페이스에 선언된 메소드는 모두 public abstract를 붙인 것과 같음.
- 디폴트 메소드(Default Method)
- 자바8
- 기존 인터페이스를 확장해서 새로운 기능을 추가하기 위해서 사용
- 정적 메소드(Static Method)
- 자바8
- 인터페이스만으로 호출 가능
- 인터페이스의 default 메소드
- java8에서 함수형 프로그래밍 요소들이 들어오면서 하위호환성을 위해 불가피하게 추가
- interface에도 구현 메소드를 가짐으로써 다중 상속의 문제점이 다시 불거짐(다이아몬드 상속 문제)
- 다중 상속 시 명확한 메소드 호출을 위해 상위 인터페이스의 메소드 명시
- 익명 클래스(Anonymous Class)
- 일회성의 구현 객체를 만들기 위해서 클래스를 새로 선언하는 것은 비효율적
- 소스 파일을 만들지 않고도 구현 객체를 만들 수 있는 방법
- 하나의 메소드를 가진 익명 클래스는 람다로 전환 가능
- 익명 클래스 역시 물리적으로는 컴파일러에 의해 .class 파일로 생성된다.(Classfile1.class 와 같이 뒤에 증가되는 숫자 값으로 파일 생성)
*추상화(Abstraction)
- 구체적인 것을 분해해서 관심 영역에 대한 특성만을 가지고 재조합 하는 것.
- 관심영역 = 어플리케이션 경계 = 도메인 = 컨텍스트
- 추상화 = 모델링 = 클래스 설계
- 추상 클래스(Abstract Class)
- 추상 메서드가 하나 이상 포함된 클래스
- Class 앞에 abstract 키워드를 붙여서 표현
- Abstract와 final 키워드는 함께 사용할 수 없다.
- Abstract 메서드는 하위 클래스에서 반드시 구현해야 한다.
- 일반 클래스처럼 new 키워드를 사용하여 생성할 수 없음.
추상클래스 vs 인터페이스
- 추상 클래스는 extends, 인터페이스는 implements 키워드 사용
- 추상 클래스는 필드를 가질 수 있지만 인터페이스는 불가능
- 인터페이스에서 Static 변수는 가질 수 있음
- 추상 클래스도 클래스이기 때문에 다중 상속이 불가능
- 다중 상속이 불가능한 제약을 인터페이스로 해결
- 인터페이스는 메서드의 구현부분과 필드가 없기 때문에 다중상속 가능
- 추상 클래스는 클래스를 상속 받아서 기능을 이용하거나 확장하는 목적
- 인터페이스는 메서드 구현을 강제하여 하위 클래스에게 같은 동작을 행하도록 함.
어떤 것을 사용할 것인가.
- 추상 메서드만으로 가능한 경우에는 인터페이스를, 공통된 구현 부분이나 필드가 필요한 경우에는 추상클래스를 사용한다.
- 애초에 클래스를 설계할 때 필드를 가질 수 없다는게 명확하면 인터페이스를 하는 것을 권장한다.
*다형성(Polymorphism)
- 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질
- 하위 클래스는 상위 클래스나 인터페이스로 자동 타입 변한이 가능
- 하위 클래스로 생성된 인스턴스는 하위클래스의 객체 참조변수에 대입되고 상위 클래스의 객체참조변수에 대입되나 같은 주소를 가리킨다.
- sub == super(객체간 == 연산자는 주소 비교)
- 상위 클래스로 변환된 경우 상위 클래스에 선언된 필드와 메서드에만 접근 가능
- 강제 타입 변환(Casting)
- 상위 클래스를 하위 클래스로 강제 변환
- instanceof로 상속관계가 맞는지 확인
- 확인 없이 다른 클래스로 캐스팅 하면 ClassCastException 발생
오버라이딩(Overrideing)
- 상속된 메서드의 내용이 하위 클래스에 맞지 않을 경우, 하위 클래스에서 동일한 메서드를 재정의 하는 것.
- 상위 클래스의 메서드는 숨겨지기 때문에 메서드 호출 시 하위 클래스의 메서드가 호출된다.
- 상위 클래스의 메서드와 동일한 시그니처를 가야한다.
- 접근 제한을 더 강하게 오버라이딩 할 수 없다.
- 새로운 예외를 throws할 수 없다.
오버로딩(Overloading)
- 클래스 내에 같은 이름의 메서드를 여러 개 선언하는 것.
- 오버로딩 된 메서드를 호출할 경우 JVM은 매개값의 타입을 보고 메서드를 선택
- 타입이 일치하지 않을 경우 타입 변환이 가능한지 검사
ETC
Call By
Call By Value : 값에 의한 전달
- 기본 자료형은 저장하고 있는 값이 전달(복사) 된다.
- 대입문 사용시 / 인자 전달 시 / 메서드 리턴 시
Call By Reference : 참조/주소에 의한 전달
- 객체참조변수에 주소값을 대입하여 힙 영역에 존재하는 객체 참조
- 포인터
static
- 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메서드
- static 필드와 메서드는 클래스에 고정된 멤버이므로 클래스 로더가 클래스(바이트 코드)를 로딩해서 메서드 메모리영역에 적재할 때 클래스별로 관리된다.
- 클래스 로딩이 끝나면 바로 사용 가능
- static 요소들은 클래스 이름으로 접근하는 것이 좋다.
- 인스턴스를 통해 접근할 경우 인스턴스를 먼저 훑고나서 없는 걸 확인한 후 클래스를 참조하기 때문에 하나의 스텝이 더 생긴다.
- static 필드는 선언과 동시에 초기값을 주는 것이 보통이지만 초기화 과정이 복잡한 경우 static 블럭을 사용할 수 있다.
- 클래스가 메모리로 로딩 될 때 자동으로 수행된다.
- 인스턴스가 없어도 실행되기 때문에 인스턴스 필드나 메서드, this 키워드를 사용할 수 없다.
인스턴스 vs static
인스턴스 필드 vs static필드
- 객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언
- 객체마다 가지고 있을 필요성이 없는 공용적인 데이터라면 static 필드로 선언
인스턴스 메서드 vs static 메서드
- 인스턴스 필드를 이용해서 실행해야 한다면 인스턴스 메서드로 선언
- 인스턴스 필드를 이용하지 않는다면 static 메서드로 선언
final
- 초기값이 저장되면 프로그램 실행 도중 수정할 수 없다.
- 필드 선언시 초기화를 하거나 생성자에서 초기화를 수행해야 한다.
- 그렇지 않으면 컴파일 에러
- static final로 상수 선언
- 클래스에만 포함되며 값을 변경할 수 없다.
- 필드 선언시 초기화를 하거나 static 블럭에서 초기화를 수행해야 한다.
- 상수 이름은 모두 대문자로 하는 것이 관례
- final method : 오버라이딩 불가능
- final class : 상속 불가능
package
- 클래스를 체계적으로 관리하기 위해 사용
- 클래스를 유일하게 만들어주는 식별자 역할
- 컴파일러는 클래스에 포함되어 있는 패키지 선언을 보고 파일 시스템의 폴더를 자동 생성
- 모두 소문자로 하는 것이 관례
- 숫자로 시작하면 안되고, _, $를 제외한 특수문자 사용 불가능
- java로 시작하는 패키지는 자바 표준 API에서만 사용하므로 사용 불가
- 보통 회사들 간에 패키지 중복을 피하기 위해 회사 도메인 이름으로 패키지를 만든다.
- 포괄적인 이름이 상위 패키지가 되도록 도메인의 역순으로 이름을 짓는다.
- 마지막에는 프로젝트 이름을 붙여주는 것이 관례
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA]SuppressWarnings (0) | 2017.05.22 |
---|---|
[JAVA]코드 효율성 (0) | 2017.05.22 |
[JAVA] 파일 이름 변경하기 (0) | 2017.01.15 |
[JAVA]VO 정렬하기 (0) | 2017.01.03 |
[JAVA]ArrayList, Array (0) | 2016.07.16 |
Comments