본문 바로가기
프로그래밍 언어/자바

4. 다시 공부하는 자바 - 객체 지향 프로그래밍 2 (이것이 자바다)

by amobu0 2024. 6. 13.

이것이 자바다 라는 책을 보고 정리한 글이다.

https://m.hanbit.co.kr/store/books/book_view.html?p_code=B4861113361

 

이것이 자바다(개정판)

2015년 초판이 출간된 이후부터 지금까지 기본 개념에 충실한 설명으로 독자들에게 큰 사랑을 받아온 『이것이 자바다』의 개정판. 기존 Java 8 버전에 최신 Java 17 LTS 버전까지 아우르는 내용으로

m.hanbit.co.kr

 

Part 2 객체 지향 프로그래밍


객체 지향 프로그래밍

현실 세계에서 어떤 제품을 만들 때는 부품을 먼저 만들고, 이 부품들을 하나씩 조립해서 완성품을 만든다. 소프트웨어를 개발할 때에도 부품에 해당하는 객체들을 먼저 만들고, 이 객체들을 하나씩 조립해서 완성된 프로그램을 만드는 기법을 객체 지향 프로그맹이라고 한다.


객체란?

객체(Object)란 물리적으로 존재하거나 개념적인 것 중에서 다른 것과 식별 가능한 것을 말한다. 예를 들어 물리적으로 존재하는 자동차, 자전거, 책, 사람은 물론 개념적인 학과, 강의, 주문 등도 모두 객체가 될 수 있다.

 

객체는 속성과 동작으로 구성된다. 사람은 이름, 나이 등의 속성과 웃다, 걷다 등의 동작이 있고, 자동차는 색상, 모델명 등의 속성과 달린다. 멈춘다 등의 동작이 있다. 자바는 이러한 속성과 동작을 각각 필드(filed)메소드(method)라고 부른다.

 

현실 세계의 객체를 소프트웨어 객체로 설계하는 것을 객체 모델링이라고 한다. 객체 모델링은 현실 세계 객체의 대표 속성과 동작을 추려내어 소프트웨어 객체의 필드와 메소드로 정의하는 과정이라고 볼 수 있다.


객체의 상호작용

현실 세계에서 일어나는 모든 현상은 객체와 객체 간의 상호작용으로 이루어져 있다. 예를 들어 사람은 전자계산기의 기능을 이용하고, 전자계산기는 계산 결과를 사람에게 리턴하는 상호작용을 한다.

 

객체 지향 프로그램에서도 객체들은 다른 객체와 서로 상호작용하면서 동작한다. 객체들 사이의 상호작용 수단은 메소드이다. 객체가 다른 객체의 기능을 이용할 때 이 메소드를 호출한다. 메소드 호출은 다음과 같은 형태를 가지고 있다.

메소드(매개값, 매개값, ......);

 

메소드 호출을 통해 객체들은 데이터를 서로 주고받는다. 메소드 이름과 함께 전달하고자 하는 데이터를 괄호( ) 안에 기술하는데, 이러한 데이터를 매개값이라고 한다. 매개값은 메소드가 실행할 때 필요한 값이다. 리턴값은 메소드의 실행의 결과이며, 호출한 곳으로 돌려주는 값이다.

int sumResult = add(10, 20);

객체와 클래스

객체를 생성할 때에는 설계도가 필요하다. 현실 세계에서 자동차는 생성하려면 자동차의 설계도가 필요하듯이, 객체 지향 프로그래밍에서도 객체를 생성하려면 설계도에 해당하는 클래스(class)가 필요하다.

 

클래스로부터 생성된 객체를 해당 클래스의 인스턴스(instance)라고 부른다. 그리고 클래스로부터 객체를 만드는 과정을 인스턴스화라고 한다.


객체 생성과 클래스 변수

클래스로부터 객체를 생성하려면 객체 생성 연산자인 new가 필요하다. new 연산자 뒤에는 생성자 호출 코드가 오는데, 클래스() 형태를 가진다. new 연산자는 객체를 생성시킨 후 객체의 주소를 리턴하기 때문에 클래스 변수에 다음과 같이 대입할 수 있다.

클래스 변수 = new 클래스();


클래스의 구성 멤버

클래스 선언에는 객체 초기화 역할을 담당하는 생성자와 객체에 포함될 필드와 메소드 코드가 포함된다. 그래서 생성자, 필드 , 메소드를 클래스 구성 멤버라고 한다.

  • 생성자(Constructor) - 객체 생성 시 초기화 역할 담당
  • 필드(field) - 객체의 데이터가 저장되는 곳
  • 메소드(Method) - 객체의 동작으로 호출 시 실행하는 블록
생성자는 new 연산자로 객체를 생성할 때 객체의 초기화 역할을 담당한다. 선언 형태는 메소드와 비슷하지만, 리턴 타입이 없고 이름은 클래스 이름과 동일하다.

필드는 객체의 데이터를 저장하는 역할을 한다. 선언 형태는 변수 선언과 비슷하지만 쓰임새는 다르다.

메소드는 객체가 수행할 동작이다. 다른 프로그램 언어에서는 함수라고 하기도 하는데, 객체 내부의 함수는 메소드라고 부른다. 매소드는 객체와 객체간의 상호 작용을 위해 호출된다.

필드 선언과 사용

필드를 선언하는 방법은 변수를 선언하는 방법과 동일하다. 단 반드시 클래스 블록에서 선언되어야만 필드 선언이 된다. 타입은 필드에 저장할 데이터의 종류를 결정한다. 기본 타입(Primitive type)과 참조 타입(Reference type)이 모두 가능하다. 필드명은 첫 문자를 소문자로 하되, 캐멀 스타일로 작성하는 것이 관례이다. 

public class Car {
    //필드 선언
    String model;   //null 초기화
    int speed;      //0 초기화
    boolean start;  //false 초기화
    TIre tire;      //null 초기화
}

 

필드를 사용한다는 것은 필드값을 읽고 변경하는 것을 말한다. 클래스에서 필드를 선언했다고 해서 바로 사용할 수 있는 것은 아니다. 필드는 객체의 데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않는다.

 

클래스로부터 객체가 생성된 후에 필드를 사용할 수 있다. 필드는 객체 내부의 생성자와 메소드 내부에서 사용할 수 있고, 객체 외부에서도 접근해서 사용할 수 있다. 

 

객체 내부에서는 단순히 필드명으로 읽고 변강할 수 있지만 외부 객체에서는 참조 변수와 도트(.)연산자를 이용해서 필드를 읽고 변경해야 한다. 도트(.)는 객체 접근 연산자로, 객체가 가지고 있는 필드나 메소드에 접근하고자 할 떄 참조 변수 뒤에 붙인다.


생성자 선언과 호출

new 연산자는 객체를 생성한 후 연이어 생성자Constructor를 호출해서 객체를 초기화하는 역할을 한다. 객체 초기화란 필드 초기화를 하거나 메소드를 호출해서 객체를 사용할 준비를 하는 것을 말한다. 생성자가 성공적으로 실행이 끝나면 new 연산자를 객체의 참조값을 리턴한다. 리터된 주소를 클래스 변수에 대입되어 객체의 필드나 메소드에 접근할 때 이용된다.

 

모든 클래스는 생성자가 존배하며, 하나 이상을 가질 수 있다. 클래스에 생성자 선언이 없으면 컴파일러는 기본 생성자를 바이트코드 파일에 자동으로 추가시킨다. 그러나 개발자가 명시적으로 선언한 생성자가 있다면 컴파일러는 기본 생성자를 추가하지 않는다. 개발자가 생성자를 선언하는 이유는 객체를 다양하게 초기화하기 위해서이다. 

 

아래와 같이 매개변수명이 필드명과 동일하기 때문에 필드임을 구분하기 위해 this 키워드를 필드명 앞에 붙여주었다. this는 현재 객체를 말하며, this.company는 현재 객체의 데이터 (필드)로서의 company를 뜻한다.


메소드 선언과 호출

메소드 선언은 객체의 동작을 실행 블록으로 정의하는 것을 말하고, 메소드 호출은 실행 블록을 실제로 실행하는 것을 말한다. 메소드는 객체 내부에서도 호출되지만 다른 객체에서도 호출될 수 있기 때문에 객체간의 상호작용하는 방법을 정의하는 것이라고 볼 수 있다.

 

메소드 호출은 메소드 블록을 실행하는 것을 말한다. 메소드는 객체의 동작이므로 객체가 존재하지 않으면 메소드를 호출할 수 없다. 객체 내부에서는 단순히 메소드명으로 호출하면 도지만, 외부 객체에서는 참조 변수와 도트(.) 연산자를 이용해서 호출한다. 또한 메소드가 매개변수를 가지고 있을 때는 호출할 때 매개변수의 타입과 수에 맞게 매개값을 제공해야 한다. 메소드가 리턴값이 있을 경우에는 대입 연산자를 사용해서 리턴값을 변수에 저장할 수 있다. 이때 변수 타입은 메소드의 리턴 타입과 동일하거나 자동 타입 변환될 수 있어야 한다.

(1)void (2)powerOn (3)( ) (4){ ... };

리턴 타입

리턴 타입은 메소드가 실행한 후 호출한 곳으로 전달하는 결과값의 타입을 말한다. 리턴값이 없는 메소드는 void로 작성해야 한다.

메소드명
매소드명은 첫 문자를 소문자로 시작하고, 캐멀 스타일로 작성한다.

매개변수
매개변수는 메소드를 호출할 때 전달한 매개값을 받기 위해 사용된다. 전달할 매개값이 없다면 매개변수는 생략할 수 있다.

실행 블록
메소드 호출 시 실행되는 부분이다.
타입 변수 = 메소드();

 

만약 메소드가 가변길이 매개변수를 가지고 있다면 매개변수의 개수와 상관없이 매개값을 줄 수 있다.

//가변길이 매개변수
int num(int ... valuse) {
}