자바의정석 Chapter6. 객체지향 프로그래밍 1


객체지향 프로그래밍이란 (Object-Oriented Programming)

  • 프로그래밍에서 필요한 데이터를 추상화 시켜서 상태(속성, 어트리뷰트)와 행위(메서드)를 가진 객체 로 만들고, 그 객체간의 상호작용을 통해 로직을 구성하는 프로그래밍 입니다.
  • 실제 세계의 사물들을 객체로 모델링하여 개발을 진행하는 프로그래밍 기법입니다.
  • 상속, 캡슐화, 추상화 개념이 구체적으로 발전되었습니다.
  • 주요 특징은 다음과 같습니다.
    1. 코드의 재사용성 - 새로운 코드를 작성할 떄 기존의 코드를 이용하여 쉽게 작성할 수 있음.
    2. 코드의 관리가 용이 - 코드간의 관계를 이용하여 적은 노력으로 코드를 쉽게 변경할 수 있음.
    3. 신뢰성 높은 프로그래밍 - 제어자와 메서드를 이용하여 데이터를 보호하고 코드의 중복을 제거하여 오동작을 방지 할 수 있음.

OOP의 6가지 키워드

  1. 클래스
    • 현실 세계의 객체를 추상화시켜, 속성과 메서드로 정의한 것 (논리적 개념)
  2. 인스턴스
    • 클래스에서 정의한 것을 토대로 만든 실제 메모리상에 할당된 것, 실제 데이터
  3. 추상화
    • 객체지향 관점에서 클래스를 정의하는 것, 불필요한 정보 외 중요한 정보만 표현함으로써 공통의 속성과 기능을 묶어 이름을 붙이는 것.
  4. 캡슐화
    • 코드를 수정없이 재활용 하는 것을 목적으로 함. 클래스라는 캡슐에 기능과 특성을 담아 묶는다. 목적을 기준으로 묶는다.
    • 은닉화와의 차이 - 은닉화는 캡슐화의 일부라고 볼 수 있으며, 목적으로 묶인 캡슐 안을 사용자는 볼 수 없다는 것이 은닉화.
  5. 상속
    • 클래스로부터 속성과 메서드를 물려받는 것을 말함. 다른 클래스를 가져와서 수정할 일이 있다면, 그 클래스를 직접 수정하는 대신 상속을 받아 변경하고자 하는 부분만 변경
  6. 다형성
    • 하나의 변수명이나 함수명이 상황에 따라 다르게 해석될 수 있음. 대표적인 다형성이 오버라이딩과 오버로딩

OOP의 5가지 법칙 (SOLID)

  1. Single Responsibility Principle, 단일 책임 법칙
    • 각 클래스는 목적을 하나씩만 가지고 그에 대한 책임을 져야 한다.
  2. Open Close Principle, 개방 폐쇄 법칙
    • 각 클래스는 클래스에 대한 수정을 폐쇄하고, 확장에 대해 개방해야 한다.
    • 즉 클래스를 수정해야 한다면 그 클래스를 상속, 즉 확장하여 수정한다.
  3. Liskov Substitusion Principle, 리스코프 치환 법칙
    • 자식 클래스를 사용 중일때, 거기에 부모 클래스로 치환하여도 문제가 없어야 한다.
  4. Interface Segreation Principle, 인터페이스 분리 법칙
    • 각 행위에 대한 인터페이스는 서로 분리되어야 한다.
    • 핸드폰을 예로 들면, 전화를 하는데 핸드폰 카메라가 방해가 되면 안된다는 말.
  5. Dependency Inversion Principle, 의존성 역전 법칙
    • 상위 클래스가 하위 클래스에 의존하면 안된다는 법칙. 즉 기본적인 공통되는 속성을 하위 클래스에 의존하면 안된다.

클래스와 객체

  • 객체의 사전적 의미는 ‘실제로 존재하는 것’
  • 클래스란 객체를 정의해놓은 것 또는 객체의 설계도 또는 틀
  • 클래스는 객체를 생성하는데 사용될 뿐 객체 그 자체는 아님.
클래스 객 체
제품설계도 제품
붕어빵 기계 붕어빵

객체와 인스턴스

  • 클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화 라고 합니다.
  • 클래스로 부터 만들어진 객체를 클래스의 인스턴스라고 합니다.
  • 클래스 —(인스턴스화)—> 인스턴스 (객체)

객체의 구성요소

  • 객체는 속성과 기능 두종류의 구성요소로 이루어져 있습니다.
  • 속성 - 맴버변수, 특성, 필드, 상태
  • 기능 - 메서드, 함수, 행위
[예제]
class Tv {
	// 속성
	String color; // 색깔 변수
	String power ; // 전원상태 변수
	
	// 기능
	void power() { power = !power; } // tv 전원 on/off 메서드
}

인스턴스의 생성과 사용

클래스명 변수명 = new 클래스명();  // 객체 초기화 (=인스턴스 초기화)

변수명.color = "red";  // 변수 사용
변수명.power(); // 메서드 사용

객체 배열

클래스의 또 다른 정의

변수의 종류

변수는 선언위치에 따라 클래스변수, 인스턴스변수, 지역변수로 나뉩니다.

변수의 종류 선언위치 생성시기 설 명
클래스 변수 클래스영역 클래스가 메모리에 올라 갈 때 static이 붙은 멤버변수
인스턴스 변수 클래스영역 인스턴스가 생성될 때 static이 붙지 않은 멤버변수
지역 변수 클래스 영역 이외의 영역 변수 선언문 수행 될 떄 멤버변수를 제외한 변수
class Variable{
	static int classVar = 1; //클래스변수
	int instanceVar = 1; // 인스턴스변수
	
	void method(){
		int localVar = 1; // 지역변수
	}	
}  

클래스변수와 인스턴스 변수

  • 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공휴하므로 공통된 값을 갖는 변수 입니다. (싱글톤 디자인패턴과 방식)
  • 인스턴스 변수는 생성되는 인스턴스별로 다른 값을 갖는 변수 입니다.

메서드

  • 메서드는 특정 작업을 수행하는 로직들을 하나로 묶은 것 입니다.
  • 메서드의 장점은 다음과 같습니다.
    1. 높은 재사용성
    2. 중복된 코드의 제거
    3. 프로그램의 구조화

메서드 선언 방법은 다음과 같습니다.

반환타입   메서드이름   (타입 변수명, 타입 변수명, ...){  // 선언부
	// 수행 로직									// 구현부
}	

인자(argument), 매개변수(parameter)

  • argument - 메서드를 호출할 때 전달되는 변수값
  • parameter - 메서드를 선언할 때 작성하는 변수명

return문

  • 현재 실행중인 메서드를 종료하고 호출한 메서드로 되돌아 가는 기능을 수행합니다.
  • 반환 타입이 void인 경우 return문이 없어도 가능했던 이유는 컴파일러가 메서드의 마지막에 return;을 자동적으로 추가 해주기 때문 입니다.

JVM의 메모리 구조

  • JVM은 시스템으로 부터 프로그램을 수행하는데 필요한 메모리를 할당받고 용도에 따라 여러 영역으로 나누어 관리 합니다.
  • 대표적인 영역으로는 method area, call stack, heap 이 있습니다.
    1. 메서드영역(method area) - 프로그램 실행 중 어떤 클래스가 사용되면 JVM은 해당 클래스의 클래스파일을 읽어서 저장함 또한 클래스 변수도 저장함
    2. 힙(heap) - new 명령어를 통해 생성된 인스턴스들이 생성되는 공간이며 GC의 대상이 되는 공간이기도 합니다.
    3. 호출스택(call stack) - 메서드의 작업에 필요한 메모리 공간을 제공 합니다.


호출스택 특징

  • 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당 받습니다.
  • 메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거됩니다.
  • 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드 입니다.
  • 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드 입니다.


기본형 매개변수와 참조형 매개변수

  • 기본형 매개변수 - 변수의 값을 일기만 할 수 있음
  • 참조형 매개변수 - 변수의 값을 읽고 변경할 수 있음

클래스 메서드(=static메서드) 와 인스턴스 메서드

  • 클래스를 설계 할 때 멤버변수 중 모든 인스턴스에 공통적으로 사용해야 하는것에 static을 붙입니다.
  • 클래스변수는 인스턴스를 생성하지 않아도 사용할 수 있습니다.
  • 클래스 메서드는 인스턴스 변수를 사용할 수 없습니다.
  • 메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 것을 고려 합니다.

클래스 멤버와 인스턴스 맴버 간 호출

  • 인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만 클래스 멤버가 존재한느 시점에 인스턴스 멤버가 존재하지 않을 수 있기 때문에
  • 클래스 멤버는 인스턴스 멤버를 호출할 때 인스턴스를 반드시 생성해야 합니다.
  • 인스턴스 멤버는 언제든 클래스멤버를 호출 가능하다.

오버로딩이란

  • 한 클래스 내에서 같은 이름의 메서드를 여러 개 정의하는 것
  • 오버로딩의 두 가지 조건
    1. 메서드 이름이 같아야 합니다.
    2. 매개변수의 개수 또는 타입이 달라야 합니다.
int add(int a, int b){};
int add(long a, long b){};
int add(int[] a){};

생성자란

  • 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드 입니다.
  • 인스턴스 생성 시에 초기화 작업을 위해 사용 됩니다.
  • 기본생성자, 매개변수가 있는 생성자가 있습니다.
  • 기본생성자는 클래스에 기본적으로 생성되는 생성자로써 선언하지 않아도 컴파일 시점에 자동으로 생성이 되어 집니다.
  • 매개변수가 있는 생성자를 선언할 경우에는 인스턴스를 생성할 때 해당 생성자를 이용하여야 합니다.
  • 생성자의 조건은 다음과 같습니다.
    1. 생성자의 이름은 클래스의 이름과 같아야 함.
    2. 생성자는 리턴 값이 없어야 함.
[예제]

class Book() {
	
	//기본 생성자
	Book() {
		// ..  
	}

	//매개변수가 있는 생성자
	Book(String id, String name){
		//...
	}
}

this(), this

  • 생성자 간의 호출은 this(), this를 사용합니다.
  • 생성자의 이름으로 클래스이름 대신 this를 사용합니다.
  • 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능합니다.
  • this - 참조변수로 인스턴스 자신을 가리키며 인스턴스의 주소가 저장되어 있습니다.
  • this - 모든 인스턴스메서드에 지역변수로 숨겨진 채로 존재합니다.
  • this() - 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용합니다.
[오류 예제]
Book(String id) {
	id = dhk5646; 
	Book(id); // 에러 1. 생성자는 첫 줄에서 호출해야 합니다.
				 // 에러2. this(id)로 호출해야 합니다.				 
}

[성공 예제]
Book(String id) {
	this(id);  // 성공. 첫 줄에서 this로 호출
	name = dhk5646;				 
}

변수의 초기화

명시적 초기화

초기화 블럭

멤버변수의 초기화 시기와 순서

  • 클래스 변수 - 클래스가 처음 로딩될 때 1회 초기화 (기본값 → 명시적 초기화 → 클래스 초기화 블럭)
  • 인스턴스 변수 - 인스턴스가 상성될 떄 마다 각 인스터별로 초기화 (기본값 → 명시적 초기화 → 인스턴스 초기화 블럭 → 생성자)

Reference

자바의 정석

태그:

카테고리:

업데이트:

댓글남기기