[Java] 자바 클래스, 생성자

최지수·2024년 6월 2일
post-thumbnail

📘자바 클래스 만들기

📌클래스와 객체

자바를 비롯한 객체 지향 언어에서, 클래스는 객체를 만들어 내기 위한 설계도 혹은 틀이며, 클래스 모양 그대로 생성된 실체가 객체이다. 이러한 연유로 객체를 클래스의 인스턴스(instance) 라고도 부른다.

클래스는 하나이지만 객체들은 수 없이 많이 생성될 수 있다. 객체들은 클래스의 모양대로 모두 동일한 속성을 가지고 탄생하지만, 자신만의 고유한 값을 가짐으로써 구분된다.


📌클래스 구성

자바 클래스는 class 키워드를 사용하여 선언한다. 클래스의 구성 요소를 멤버라고 부르며, 멤버는 필드(멤버 변수)와 메소드(멤버 함수)의 두가지이다.

이 예시는 원을 추상화한 클래스 Circle을 작성한 코드를 보여준다.
구체적으로 알아보자.

클래스 선언, class Circle

이 코드는 이름이 Circle인 클래스를 선언한다. class 키워드와 클래스 이름으로 선언하고 중괄호({}) 안에 필드(field)와 메소드(method)를 모두 작성한다. 클래스 외부에는 어떤 필드나 메소드를 둘 수 없다. 캡슐화의 원칙 때문이다.

필드와 메소드

객체 내에 값을 저장할 멤버 변수를 필드라고 부른다. Circle 클래스에는 radius와 name의 두 필드가 있다. 메소드는 함수이며 객체의 행동을 구현한다. getArea() 메소드는 Circle 객체의 반지름 정보(radius)를 이용하여 면적을 계산하여 알려준다.

접근 지정자, public

Circle이나 필드, 메소드에 붙은 public을 접근 지정자(access specifier)라고 한다. public은 다른 클래스에서 활용하거나 접근할 수 있음을 선언한다. 접근 지정자를 생략할 때 디폴트 접근이라고 부른다.

생성자(constructor)

클래스의 이름과 동일한 메소드를 특별히 생성자(constructor)라고 한다. 생성자는 객체가 생성될 때 자동으로 호출되는 특별한 메소드이다.


📌new 연산자와 객체 생성, 그리고 레퍼런스 변수

레퍼런스 변수 선언

객체를 생성하기 전 객체를 가리킬 레퍼런스 변수를 먼저 선언한다. 다음은 Circle 타입의 객체를 가리킬 레퍼런스 변수 pizza를 선언하는 문장이다.

Circle pizza;  // 레퍼런스 변수 pizza 선언

이 선언문으로는 Circle 타입의 객체가 생성되지 않는다. 변수 pizza는 Circle 클래스의 객체에 대한 주소, 정확히 말해 레퍼런스를 가지는 변수일 뿐 객체 자체는 아니다. 따라서 아직 객체가 생성된 것이 아니며, 레퍼런스 변수만 생기고 null로 초기화된다.

객체 생성, new 연산자 이용

자바에서는 반드시 new 연산자를 사용하여 다음과 같이 객체를 생성한다.

pizza = new Circle();

생성된 Circle 객체의 주소 즉 레퍼런스를 pizza 변수에 대입한다. new 연산자에 의해 객체가 생성되는 과정은 다음과 같다.

  • Circle 타입 크기의 메모리 할당
  • Circle() 생성자 코드 실행

pizza 객체는 radius와 name 필드가 초기화되지 않은 상태로 생성되었다. 객체가 생성될 때 필드를 초기화하거나 생성 당시에 꼭 필요한 작업을 위해 두는 것이 생성자인데, 현재 Circle() {} 생성자에는 아무 코드가 작성되지 않아 아무 작업도 실행되지 않았다.

레퍼런스 변수 선언과 객체 생성은 다음과 같이 동시에 할 수도 있다.

Circle pizza = new Circle();

📌객체 멤버 접근

객체의 멤버에 접근할 때는 다음과 같이 레버런스 변수 뒤에 점(.) 연산자를 붙인다.

객체 레퍼런스.멤버

예를 들어, 다음 코드는 pizza 객체의 radius 필드에 10을 대입한다.

pizza.radius = 10;

이 코드의 실행 결과는 radius 필드 값이 10으로 바뀌었다. pizza 객체의 radius 필드 값을 읽을 경우 다음과 같이 하면 된다.

int r = pizza.radius;

다음 코드는 pizza 객체의 getArea() 메소드를 호출하여 면적을 알아낸다.

double area = pizza.getArea();


📘생성자

📌생성자의 개념과 목적

생성자(constructor)는 객체가 생성될 때 객체의 초기화를 위해 실행되는 메소드이다.


📌생성자 선언 및 활용

생성자는 객체가 생성되는 순간에 자동으로 호출되는 메소드로서, 객체에 필요한 초기화를 실행하는 코드를 담아야 한다.

생성자의 이름

생성자의 이름은 반드시 클래스 이름과 동일하게 작성해야 한다.

public class Circle {
    public Circle(int r, String n) {  // 생성자
        ...
    }
}

생성자 작성

매개변수의 개수와 타입만 다르다면, 클래스 내에 생성자를 여러개 둘 수 있다. Circle 클래스 역시 매개변수의 개수가 다른 2개의 생성자가작성되어 있다.

public calss Circle {
    public Circle() {   // 매개변수 없는 생성자
        ...
    }
    
    public Circle(int r, String n) { // 2개의 매개 변수를 가진 생성자
        ...
    }
}

생성자 호출

객체 생성은 반드시 new를 통해서만 이루어지며, 생성자는 이 때 자동으로 한번만 호출된다. 호출하고 싶을 때 아무 때나 호출할 수 있는 메소드가 아니다.

// 생성자 Cricle(int r, String n) 호출
Circle pizza = new Circle(10, "자바");  
Circle donut = new Circle();  // 생성자 Circle() 호출

생성자 리턴 타입

생성자는 어떤 값도 리턴하지 않기 때문에 다음과 같이 리턴 타입을 선언해서는 안된다.

public Circle() {  // 리턴 타입 선언하지 않음
    ...
}

리턴 값이 없다고 해서, void를 리턴 타입으로 지정하면 안 된다.3

하지만 생성자에서 return 문을 사용할 수 없다는 뜻은 아니다. return 문은 메소드의 실행을 끝내고 호출한 곳으로 돌아가라는 명령이므로, 생성자의 실행을 끝내고자 하면 생성자 코드 내 어디서든 return; 문을 사용하면 된다.

생성자 목적

다음 객체 생성문은 Circle(int r, String n) 생성자를 호출하며 pizza 객체의 radius를 10으로, name을 "자바"로 초기화한다.

Circle pizza = new Circle(10, "자바");
// 생성자 Circle(int r, String n) 호출

📌기본 생성자

기본 생성자(default constructor)란 매개변수와 실행 코드가 없어 아무 일도 하지 않고 단순 리턴하는 생성자이다. 디폴트 생성자라고도 부르며 예를 들면 다음과 같다.

class Circle() {
    public Circle() { } 
    // 기본 생성자. 매개변수 없고 아무 일 없이 단순 리턴
}

기본 생성자가 자동으로 생성되는 겨웅

생성자가 없는 클래스는 있을 수 없다. 객체가 생성될 때 반드시 생성자가 실행되기 때문이다. 그러므로 생성자가 하나도 없는 경우, 컴파일러는 기본 생성자를 자동으로 생성한다.

기본 생성자가 자동으로 생성되지 않은 경우

생성자가 하나라도 존재하는 클래스에는 컴파일러가 기본 생성자를 삽입해 주지 않는다. 이미 생성자가 있는 Circle 클래스와 Circle의 객체를 생성하는 두 가지 경우를 보여준다. 먼저 다음 new 문장을 보자.

Circle pizza = new Circle(10); // Circle(int r) 호출

이 new 문장은 매개변수를 가진 다음 생성자를 호출한다.

public Circle(int r) {
    radius = r;
}

그러나 다음 new 문장을 위한 생성자 Circle()은 작성되어 있지 않다.
```java
Circle donut = new Circle() // 컴파일 오류. 생성자 Circle() 없음

Circle 클래스에는 매개변수를 가진 생성자가 작성되어 있지 않기 때문에 컴파일러는 기본 생성자를 만들어주지 않는다. 그러므로 앞의 new 문장은 컴파일 오류를 발생시킨다.


📌this 레퍼런스

this는 자바의 중요한 키워드로서 단어 뜻 그대로 객체 자신을 가리키는 레퍼런스이다.

this의 기초 개념

this는 현재 객체 자신에 대한 레퍼런스이다. 보다 정확히 말하면 현재 실행되고 있는 메소드가 속한 객체에 대한 레퍼런스이다. this는 컴파일러에 의해 자동 관리되므로 개발자는 this를 사용하기만 하면 된다. 다음 코드는 this를 사용하는 전형적인 예이다.

public class Circle {
    int radius;
    public Circle(int r) { this.radius = r; }
    public int getRaduis() { return radius; }

this는 현재 객체에 대한 레퍼런스이므로, this.radius는 현재 객체의 멤버 radius를 접근한다.

this의 필요성

앞의 Circle 클래스에서 메소드 getRadius()는 다음과 같이 this를 사용하지 않았다. 클래스 내에서 멤버 radius를 접근할 때 굳이 this.radius로 할 필요가 없다.

return radius;  // return this.radius;와 동일

매개변수의 이름은 그 자체로서 코드를 읽는 사람에게 그 용도를 나타내므로, 적합한 이름을 붙이는 것은 매우 중요하다. 그래서 Circle(int r) 생성자의 매개변수를 r 대신 다음과 같이 radius로 변경하는 것이 좋다.

public Circle(int radius) { radius = radius; }

this 사용 시 주의할 점

  • this()는 반드시 생성자 코드에서만 호출할 수 있다.
  • this()는 반드시 같은 클래스 내 다른 생성자를 호출할 때 사용된다.
  • this()는 반드시 생성자의 첫 번째 문장이 되어ㅑㅇ 한다.
profile
오늘보다 내일 더 성장하는 개발자🌱

0개의 댓글