본문 바로가기
Java | Spring

클래스

by HongK 2021. 2. 11.

목표

자바의 Class에 대해 학습하기


클래스를 정의하는 방법

객체는 세상에 존재하는 유일무이한 사물이다. 이러한 객체는 생물이건 무생물이건 속성과 기능을 가지고 있다고 볼 수 있다. 클래스는 같은 속성과 기능을 가진 객체를 총칭하는 분류와 집합의 개념이다.

 

사람은 클래스인가? 객체인가?

김연아는 클래스인가? 객체인가?

뽀로로는 클래스인가? 객체인가?

펭귄은 클래스인가? 객체인가?

 

만약 위의 질문에 답을 할 수 없다면 아래와 같은 질문에 답을 해보자.

 

사람의 나이는 몇 살인가?

김연아의 나이는 몇 살인가?

뽀로로의 나이는 몇 살인가?

펭귄의 나이는 몇 살인가?

 

객체는 실체이며, 클래스는 분류에 대한 개념이다. 속성에 대한 명확한 답을 찾을 수 있는 것이 객체이며, 답을 낼 수 없는 것은 클래스다. 즉 사람과 펭귄은 클래스이고 김연아와 뽀로로는 객체이다.

 

사람이라는 클래스를 만든다고 해보자. 클래스를 만들기 위해서는 실체들 , 즉 사람 객체들을 관찰해서 사람 객체들이 가진 공통된 특성을 찾게 된다. 객체는 속성과 기능을 가지고 있으므로, 사람의 공통된 속성과 기능을 생각해보자.

사람
이름

몸무게
혈액형
나이
회사
직책
연봉
...
먹다()
자다()
운동하다 ()
출근하다 ()
일하다()
퇴근하다 ()
야근하다 ()
...

이렇듯 사람의 공통된 속성과 기능은 너무 많다. 클래스는 사람의 공통된 특성을 모두 나열해야할까? 답은 NO!

클래스는 클래스가 정의되어야할 어플리케이션의 경계, 즉 컨텍스트(Context) 안에 있는 특성만을 가진다. 이렇게 대상들의 구체적인 특성을 분해해서 관심영역 (어플리케이션 경계, context)에 맞는 특성만 가지고 조합하는 것, 즉 클래스를 설계하는 과정을 추상화(Abstraction) 또는 모델링(Modeling)이라고 한다.

병원 어플리케이션
사람 (환자)
이름

몸무게
혈액형
나이
회사
직책
연봉
먹다()
자다()
운동하다 ()
출근하다 ()
일하다()

퇴근하다 ()
야근하다 ()

클래스는 어플리케이션 경계 내에서 객체들이 가지는 공통적인 속성(property)과 기능(function)을 정의하며, 일반적으로 다수의 속성과 다수의 기능을 갖는다. 속성과 기능을 다루는 여러 용어들이 있는데, 속성은 멤버변수(member variable), 기능은 메소드(method)로 주로 사용된다. 위의 병원 어플리케이션의 사람(환자) 클래스는 아래와 같이 코드로 정의할 수 있다.

public class Patient {
    private String name;
    private double height;
    private double weight;
    private String bloodType;
    private int age;

    public void eat() {
        System.out.println("냠냠");
    }
    public void sleep() {
        System.out.println("쿨쿨");
    }
    public void exercise() {
        System.out.println("으쌰");
    }  
}

 

 

객체 만드는 방법 (new 키워드 이해하기)

클래스로부터 객체, 인스턴스를 생성하는 방법은 대표적으로 아래와 같이 한다.

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

Patient patient = new Patient();

 

  1. 먼저, Patient 타입의 참조변수 patient 를 위한 저장 공간이 마련된다.
  2. new 에 의해 Patient 클래스의 인스턴스가 JVM 메모리 영역 중 Heap 영역에 생성된다. 이 때, 멤버변수는 기본값으로 초기화 된다.
  3. 대입연산자에 의해서 인스턴스가 생성된 주소값이 참조변수 patient에 저장된다.
    인스턴스의 멤버변수에 접근하고, 인스턴스의 메소드를 호출하기 위해서는 참조변수를 통해서만 가능하다.

 

메소드 정의하는 방법

메소드는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다. 기본적으로 수학의 함수와 유사하며, 어떤 값을 입력하면 작업을 수행해서 결과값을 반환한다. 메소드를 사용하는 이유는 높은 재사용성, 중복코드의 제거, 프로그램의 구조화 등이 있다.

 

메소드는 크게 두 부분, 선언부와 구현부로 이루어져 있다.

반환타입 메서드이름 (타입 변수명, 타입 변수명) {
    System.out.println("구현부분");
}

int add(int leftOperand, int rightOperand) {
    return leftOperand + rightOperand;
}

메소드 선언부(method declaration, method header)

반환타입 (return type)

메소드의 작업수행 결과인 반환값(return value)의 타입을 적는다. 반환값이 없는 경우 반환타입으로 void를 적어야한다.


메소드의 이름 (method name)

메소드는 특정 작업을 수행하므로 메소드의 이름은 동사로 시작하며, 이름만으로도 메소드의 기능을 쉽게 알 수 있도록 함축적이면서도 의미있는 이름을 짓도록 노력해야한다.


매개변수 선언 (parameter declaration)

매개변수는 메소드가 작업을 수행하는데 필요한 값들을 제공받기 위한 것이며, 필요한 값의 개수만큼 변수를 선언하며 각 변수 간의 구분은 쉼표 ','를 사용한다.


메소드의 구현부 (method body)

return 문

메소드의 반환타입이 void가 아닌 경우, 구현부 안에 'return 결과값;' 이 반드시 포함되어 있어야 한다. 이 값의 타입은 반환타입과 일치하거나 자동 형변환이 가능한 것이어야 한다.

 

 

생성자 정의하는 방법

생성자는 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메소드이다. 따라서 인스턴스 변수의 초기화 작업이나, 인스턴스 생성 시에 실행되어야 할 작업을 위해 정의된다.

class Patient {
    private String name;
    private int age;

.....
    
    Patient() {
        System.out.println("매개변수가 없는 생성자");
    }
    Patient(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("매개변수가 있는 생성자");
    }    
}

생성자 역시 메소드처럼 클래스 내에 선언되며, 구조도 메소드와 유사하지만 반환값이 없다는 점이 다르다. (void도 적지 않는다.)

생성자도 오버로딩이 가능하므로 하나의 클래스에 여러개의 생성자가 존재할 수 있다. 객체는 new 연산자가 생성하는 것이지, 생성자가 생성하는 것은 아니다. new 연산자가 클래스의 인스턴스를 생성하여 메모리에 저장하면, 생성자가 호출되어 수행된다.

 

기본 생성자

모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야한다. 컴파일 할 때, .java 파일의 클래스에 생성자가 하나도 정의되지 않은 경우에는 컴파일러가 자동으로 기본 생성자를 추가하여 컴파일 해준다. 이 때, 기본 생성자는 매개변수도 없고 수행 구문도 없는 형태이다.

Patient () {}

 

 

this 키워드 이해하기

생성자나 메소드의 매개변수와 인스턴스 변수명이 동일한 경우, 변수명만 작성하면 지역변수인 매개변수의 우선순위가 높아 지역변수를 가리키게 된다. 이 때, 인스턴스 변수를 특정하기 위해 this를 사용한다.

Patient(String name, int age) {
    this.name = name;
    this.age = age;
}

void updateAge(int age) {
    age = age; // (매개변수) age = (매개변수) age
    this.age = age;  // (인스턴스 변수) age = (매개변수) age
}

this는 인스턴스 자신을 가리키는 참조변수로 인스턴스의 주소가 저장되어 있다. 생성자를 포함한 모든 인스턴스 메소드에는 자신이 관련된 인스턴스를 가리키는 참조변수 this가 숨겨진 채로 존재한다. 인스턴스를 가리키는 참조변수이기 때문에 객체를 생성하지 않은 채로 수행되는 static 메소드에서는 접근이 불가하다. 

this(), this(매개변수) 는 생성자에서 같은 클래스 내의 다른 생성자를 호출할 때 사용한다.

 

 

 

※ 참고

Java의 정석

 

Java의 정석

최근 7년동안 자바 분야의 베스트 셀러 1위를 지켜온 '자바의 정석'의 최신판. 저자가 카페에서 12년간 직접 독자들에게 답변을 해오면서 초보자가 어려워하는 부분을 잘 파악하

m.yes24.com

스프링 입문을 위한 자바 객체 지향의 원리와 이해

 

스프링 입문을 위한 자바 객체 지향의 원리와 이해

자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량 애플리케이션 프레임워크인 스프링은 자바와 객체 지향이라는 기반 위에 굳건히 세워져 있다. 따라서 스프링을 제대로 

m.yes24.com

 

'Java | Spring' 카테고리의 다른 글

패키지  (0) 2021.02.11
상속  (0) 2021.02.11
연산자  (0) 2021.02.05
자바 데이터 타입, 변수 그리고 배열  (0) 2021.02.02
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가  (0) 2021.02.01