[자바의정석] Ch.06 객체 지향 1

maroo·2023년 3월 5일
0

객체와 클래스, 인스턴스

객체 = 사물, 개념, 논리, 클래스의 정의대로 메모리에 생성된 대상
클래스 = 객체를 찍어내는 틀, 객체를 정의하는 것
인스턴스 = 클래스로부터 만들어진 객체


객체의 필요성

  • 매번 새로 선언해줘야 하는 불편함
  • 프로그램 수행 과정에서 시,분,초가 뒤섞여 올바르지 않은 데이터가 될 가능성

class Time{
int hour;
int miniute;
float second;
}

시, 분, 초를 저장하기 위한 세 변수를 멤버 변수로 가지면서
시, 분, 초를 하나로 묶는 사용자 정의 타입(클래스)를 정의해서 사용


객체의 구성 요소 - 속성과 기능

속성 property : 멤버 변수, 특성, 필드, 상태
기능 function : 메서드, 함수, 행위


변수 : 객체의 속성

멤버 변수 (인스턴스 변수, 클래스 변수), 지역 변수

1. 인스턴스 변수

클래스 영역에 선언, 인스턴스를 생성할 때 만들어짐. 따라서 인스턴스 변수 값을 읽어오거나 저장하기 위해서는 먼저 인스턴스를 생성해야한다. 인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다. 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스 변수로 선언한다.

2.클래스 변수 (static변수, 공유 변수)

인스턴스 변수 앞에 static을 붙이면 된다. 모든 인스턴스가 공통된 변수를 공유하게 된다. 한 클래스 내의 모든 인스턴스 들이 공통적인 값을 유지해야하는 속성의 경우, 클래스 변수로 선언해야 한다. 인스턴스를 생성하지 않고도 바로 사용할 수 있고, '클래스이름.클래스변수'와 같은 형식으로 사용한다. public을 앞에 붙이면 같은 프로그램 내 어디서나 접근할 수 있는 전역변수(global variable)의 성격을 갖는다.

3. 지역 변수

메서드 내에 선언되어 메서드 내에서만 사용가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다. 선언된 블럭{} 내에서만 사용 가능.

class Card{
String kind; // 무늬 인스턴스변수
int number; // 숫자 인스턴스변수
static int width = 100; // 폭 클래스변수
static int height = 250; // 높이 클래스변수
}


메서드 : 객체의 기능

특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것, 함수와 유사. 어떤 값을 입력하면 이 값으로 작업을 수행하여 결과를 반환.
sqrt(), println(), random()..

메서드를 사용하는 이유

  1. 높은 재 사용성 (reusability)
    자바 API에서 제공하는 메서드들을 사용, 내가 만든 메서드도 재사용,,
  2. 중복된 코드 제거
    반복되는 코드 대신 메서드를 호출
  3. 프로그램의 구조화
    작업단위를 나누어서 메서드로 만들면 프로그램의 구조를 단순화 시킬 수 있고, 전체 흐름이 한눈에 들어와 문제가 발생해도 쉽게 찾아서 해결할 수 있다.

메서드의 선언과 구현

메서드의 선언부는 후에 변경사항이 발생하지 않도록 신중히 작성해야한다. 메서드의 선언부를 변경하게 되면, 그 메서드가 호출되는 모든 곳도 같이 변경해야 하기 때문이다.

매개 변수는 필요한 값의 개수만큼 변수를 선언하며, 두 변수의 타입이 같아도 변수의 타입을 생략할 수 없고 하나하나 선언해줘야 한다. 변수 간 구분은 쉼표. 값을 입력받을 필요가 없다면 괄호 안에 아무 것도 적지 않는다.

메서드의 작업 수행 결과(출력)인 반환값return value의 타입을 적는다. 구현부의 작업을 수행한 결과인 반환값이 메서드 선언부에서 정한 타입이 일치하거나 적어도 자동 형변환이 가능한 것이어야 한다.

반환값이 없는 경우 반환 타입으로 void를 적어야 한다. void가 아닌 경우는 return 값이 반드시 존재해야한다.
구구단 전체를 출력하는 메서드 예시

입력이 없고, 입력값에 대한 출력이 따로 없으므로 반환타입이 void.

메서드의 호출

인자(argument) 메서드를 호출할 때 괄호()안에 지정해준 값들을 인자 또는 인수라고 한다.


인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야한다. 인자는 메서드가 호출되면서 매개변수에 대입되므로 타입이 일치하거나 자동 형변환이 가능해야한다.

return문

모든 메서드에는 적어도 하나의 return이 있어야하는데, void일 때 return을 쓰지 않아도 되는 건 컴파일러가 자동으로 추가해주기 때문이다.


if문의 조건식의 결과에 따라 return문이 실행되지 않을 수도 있는 위 코드는, else문을 추가해서 항상 결과값이 반환되도록 해야한다.


반환값에 수식을 적어 간단히 할 수 있다. 수식이 반환되는 것이 아니라 수식의 계산 결과가 반환된다.


인스턴스의 생성과 사용


매개변수 (기본형/참조형)

메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다. 매개변수의 타입이 기본형일 때는 기본형 값이 복사되고, 참조형이면 인스턴스의 주소가 복사된다. 기본형으로 선언하면 단순히 저장된 값을 가져오기만 하지만(read only), 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어오고 변경하는 것도 가능하다(read & write).


1. 메서드가 호출되면서 'd.x'가 change메서드의 매개변수 x에 복사됨
2. change메서드에서 x의 값을 1000으로 변경
3. 메서드가 종료되면서 매개변수x는 스택에서 제거됨
-> d.x의 값이 변경된 것이 아니라, 메서드의 매개변수의 값이 변경된 것이고, 복사본이 변경되었을 뿐 원본에는 영향을 미치지 못한다.


1. 메서드가 호출되면서 참조변수 d의 값(주소)이 매개변수d에 복사됨. 이제 매개변구 d에 저장된 주소값으로 x에 접근가능
2. 메서드의 매개변수 d로 x의 값을 1000으로 변경
3. 메서드가 종료되면서 매개변수 d는 스택에서 제거
-> 참조형으로 선언했기 때문에, x의 값이 아닌 x의 주소가 매개변수 d에 복사되었고, 메인메서드와 change메서드의 참조변수는 같은 객체를 가리키게 되었다. 그래서 변경이 가능하다.


재귀호출 recursive call

메서드 내부에서 자기 자신을 다시 호출하는 것을 재귀호출이라 한다. 재귀호출을 하는 메서드를 재귀 메서드라 한다. 재귀호출은 무한반복에 빠지지 않고 언젠가 종료를 하도록 조건문이 필수이다. 대부분의 재귀호출은 반복문으로 작성하는 것도 가능한데, 논리적 간결함, 단순한 구조로 알아보기 쉽게 작성하는 장점때문에, 반복적으로 처리해야하는 작업은 재귀호출로 간단히 할 수 없는지 고민해볼 필요가 있다.

int factorial (int 4) { return 4 factorial(3); }
int factorial (int 3) { return 3
factorial(2); }
int factorial (int 2) { return 2 * factorial(1);}


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

클래스메서드는 static을 붙인다.
클래스 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.
클래스 메서드는 인스턴스 변수를 사용할 수 없다.
메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 걸 고려한다.

인스턴스 메서드는 인스턴스 변수 만으로 충분히 작업이 가능하기 대문에 매개변수를 필요로 하지 않으므로 괄호() 안에 매개 변수를 선언하지 않는다.
인스턴스 변수 없이 매개변수 만으로 작업을 수행하면 static을 붙인다(클래스 메서드).

0개의 댓글