[JAVA] 9. 클래스 기본 구성 요소 및 특징

Re_Go·2024년 5월 26일
0

JAVA

목록 보기
10/37
post-thumbnail

1. 클래스의 기본 구성 요소

앞서 살펴본 자바에서의 클래스를 이용한 객체 생성 요소에는 기본적으로 필드(field), 생성자(constructor), 메서드(method) 세 가지로 구성되며 자바스크립트의 class를 이용한 객체 생성과도 유사합니다. 각각의 요소들의 특징은 다음과 같습니다.

필드(field)

클래스에 정의된 기본 속성을 나타내는 변수입니다. 데이터들의 종류와 속성을 정의하며 제품의 '구성 재료' 라고 보면 이해하기 쉬운데, 클래스의 필드를 토대로 각 객체들의 속성이 확정됩니다.

이러한 필드에는 클래스를 정의할 때 여러 값으로 미리 초기화 할 수 있으며, 생성자를 이용해 전달 받을 때 값을 할당할 수도 있습니다. (클래스를 정의할 때 미리 할당 되어 있던 값은 생성자가 매개변수를 할당할 때 덮어씌여집니다.)

이러한 필드에서는 기본적으로 소문자로 네이밍을 하지만, 상수와 같은 값을 쓰고자 할 때는 대문자로 작성해 주시면 됩니다.

    // 1. 필드(Fields) : 전달된 생성자의 속성들을 바탕으로 각 객체의 속성을 할당합니다.이때 초기화로 기본 값을 할당할 수도 있으며, 생성자에 의해 전달된 값이 있을 경우 그 값으로 덮어씌여집니다. 
    public String name = "None"; // 공개된 변수 (초기화)
    private int age = 0;      // 제한된 변수
    private static final ID = 5; // // 극히 제한된 상수

생성자(constructor)

클래스의 인스턴스가 생성될 때 호출되는 특별한 메서드입니다. 인스턴스를 초기화하고 필요한 작업을 수행하는 역할을 합니다. 구체적으로 말하자면 '구성 재료(필드)'를 전달된 재료(매개변수)로 정하는 작업으로 볼 수 있으며, 생성자는 클래스와 동일한 이름을 가지고, 반환 타입을 지정하지 않습니다. 참고로 이 생성자는 생략이 가능하며, 생략시 컴파일에서 자동으로 기본 생성자를 생성합니다. (우리 눈에 안보일 뿐)

하지만 우리가 다른 생성자를 만들었다면 기본 생성자는 자동으로 생성되지 않기 때문다른 매개변수를 받을 생성자를 만든다고 할 때 아무것도 받지 않는 기본 생성자도 함께 만들어 주는 것을 권고합니다.

이러한 생성자 또한 메서드와 같지만, 인스턴스를 생성하는 역할을 하기 때문메서드와의 역할을 구분 짓기 위해 클래스 이름과 똑같이(첫 글자를 대문자로) 작성 해주면 됩니다.해 주면 됩니다.

마지막으로 생성자를 호출하여 객체를 생성하기 위해서는 new 키워드 > 생성자 > 매개변수 할당 순으로 작성하면 됩니다.

// 2. 생성자(Constructor) : new 키워드와 함께 호출됩니다.
    public Person(String n, int a) {
        this.name = n; // this는 현재 생성되는 객체의 필드 속성을 의미합니다.
        this.age = a;
    }

// Person 생성자를 호출해 Person 인스턴스 생성
People person1 = new Person("Re_Go", 30) 

메서드(method)

클래스가 제공하는 기능을 정의하는 함수입니다. getter와 setter 및 사용자 정의 메서드나 라이브러리 클래스의 메서드를 포함할 수 있으며, 이러한 메서드들을 이용해 필드의 값을 조작하거나 클래스의 동작을 수행하는데 사용됩니다.

이러한 메서드를 선언할 때에는 접근 제한자 > 반환 타입 > 메서드 이름 순으로 작성하며, 이때 반환 값이 없을 경우 반환 타입에 void를 작성하고, 반환 값이 있을 경우 반환 타입을 적어주고 메서드의 마지막 코드 라인에 return 키워드로 반환할 값을 넣어줍니다. (참고로 메서드는 return 문을 만나면 종료됩니다.)

정의 할 때는 클래스 및 생성자와 다르게 소문자(카멜 케이스)를 사용하여 생성합니다.

//  반환 타입이 있는 메서드라서 반환 타입(String)과 반환문(return name)이 삽입됩니다.
    public String getName() {
        return name;
    }

//  반환 타입이 없는 메서드라서 void를 삽입하고 return문을 생략합니다.
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void greet() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }

지금까지 설명했던 위의 필드, 생성자, 메서드를 합친 클래스를 생성하는 골자는 아래의 코드와 같습니다.

public class Person {
    private String name = "None"; // 이름 (초기화)
    private int age = 0;      // 나이 
>
    public Person(String n, int a) {
        this.name = n; // this는 현재 생성되는 객체의 필드 속성을 의미합니다.
        this.age = a;
    }
>
    public String getName() {
        return name;
    }
>
    public void setName(String name) {
        this.name = name;
    }
>
    public int getAge() {
        return age;
    }
>
    public void setAge(int age) {
        this.age = age;
    }
>
    public void greet() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }
}

2. 메서드 오버로딩

이렇듯 자바의 객체들은 주로 클래스를 이용해 생성되는데요. 이때 객체들마다도 공통된 특징이 있고, 개별된 고유 특징이 있을 수도 있잖아요? 이때 생성자의 이름은 같되 매개변수(속성)가 다를 때마다 또 생성이 가능하도록 할 수 있는데, 이를 오버로딩 이라고 부르며,

오버로딩은 클래스 생성시 필드를 제외한 생성자와 메서드에 적용이 가능합니다. 주요 사용법은 네이밍이 같은 상태에서 매개변수만 다르게 받아 적용하는 법이며, 생성자 생성 방법은 다음과 같습니다.

public class Person {
    // 1. 필드(Fields)
    private String name; // 이름
    private int age;      // 나이

    // 2. 생성자(Constructor)
    public Person(String n, int a) {
        this.name = n; // this는 현재 생성되는 객체의 필드 속성을 의미합니다.
        this.age = a;
    }

    // 생성자 오버로딩: 이름만 받는 생성자
    public Person(String n) {
        this.name = n;
        this.age = 0; // 기본값으로 0 할당
    }

    // 생성자 오버로딩: 나이만 받는 생성자
    public Person(int a) {
        this.name = "Unknown"; // 기본값으로 "Unknown" 할당
        this.age = a;
    }

    // 생성자 오버로딩: 매개변수가 없는 기본 생성자
    public Person() {
        this.name = "Unknown";
        this.age = 0;
    }
 
    // 메서드 오버로딩: 기본 인사 메서드
    public void greet() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }

    // 메서드 오버로딩: 특정 메시지를 포함한 인사 메서드 (리턴 타입은 달라도 되나, 이름은 같아야 하며 타입 개수나 순서를 달리하여 적용합니다.)
    public void greet(String message) {
        System.out.println(message + ", my name is " + name + " and I am " + age + " years old.");
    }

    // 메서드 오버로딩: 특정 나이를 포함한 인사 메서드
    public void greet(int customAge) {
        System.out.println("Hello, my name is " + name + " and I am " + customAge + " years old.");
    }
}

3. 생성자 체이닝

생성자는 매개변수의 작성 개수에 따라 처리할 오버로딩 생성자를 구현할 때 전달 받은 매개변수를 간단하게 필드에 할당하는 방법이 있는데요. 이러한 기술을 생성자 체이닝 이라고도 하며, 메서드 오버로딩과 비슷하다고 보시면 됩니다.

this 안에 할당할 값들은 필드에 나열된 멤버들의 순서대로 맞게 입력해 주어야 하는데요. 그 예시는 다음과 같습니다.

 // 1. 필드(Fields)
    private String name;  // 이름
    private int age;      // 나이
    private boolean marriage; // 결혼 여부

    // 전달받는 매개변수가 세 개일 때
    public Person(String name, int age, boolean marriage) {
        // this() 호출이 아닌, 필드에 직접 할당
        this.name = name;
        this.age = age;
        this.marriage = marriage;
    }

    // 매개변수를 받지 않을 때 생성자를 기본 속성으로 지정
    public Person() {
        this("Re_Go", 30, false);  // 문자열 리터럴은 따옴표로 감쌉니다
    }

    // 전달받는 매개변수가 하나일 때
    public Person(String name) {
        this(name, 30, false);
    }

    // 전달받는 매개변수가 두 개일 때
    public Person(String name, int age) {
        this(name, age, false);
    }

4. 정적 멤버 (Static)

클래스가 포함하고 있는 정적 생성자나 정적 메서드를 의미하며, 생성자나 메서드의 앞 부분에 static 키워드를 붙이는 것으로 생성이 가능합니다.

static 키워드가 붙어 있는 멤버의 경우 클래스 내에서 자체적으로 고유하고있는 요소로서 모든 객체가 해당 필드를 공유하거나, 따로 객체를 생성하지 않고도 클래스를 직접 호출하여 접근 및 사용이 가능합니다.

클래스 내에 정적 블록(static {}) 내에서는 인스턴스 멤버를 사용하는것이 허용되지 않으므로, 정적 블록에서 인스턴스 멤버를 사용하고자 할 경우 클래스 내에 객체를 생성하는 코드문을 작성한 뒤 생성도니 객체(인스턴스 멤버)를 이용하여 인스턴스 멤버를 정적 블록 내에 사용하는 방법을 사용해야 합니다.

public class Person {
    // 정적 필드: 모든 인스턴스가 공유하는 상수, 참고로 final 키워드는 생성과 동시에 초기화를 진행하는 상수 키워드를 의미합니다.
    public static final String DEFAULT_NAME = "Unknown"; 

    // 정적 메서드: 모든 인스턴스에 동일하게 적용되는 기능
    public static void printDefaultName() {
        System.out.println("Default name: " + DEFAULT_NAME);
    }

    // 인스턴스 필드
    private String name;
    private int age;
    private boolean marriage;

    // 생성자
    public Person() {
        // 기본 생성자
        this(DEFAULT_NAME, 30, false);
    }

    public Person(String name) {
        // 이름만을 매개변수로 받는 생성자
        this(name, 30, false);
    }

    public Person(String name, int age) {
        // 이름과 나이를 매개변수로 받는 생성자
        this(name, age, false);
    }

    public Person(String name, int age, boolean marriage) {
        // 모든 필드를 매개변수로 받는 생성자
        this.name = name;
        this.age = age;
        this.marriage = marriage;
    }

    // 인스턴스 메서드: 각 인스턴스에 의존하는 동작
    public void introduce() {
        System.out.println("Name: " + name + ", Age: " + age + ", Marriage: " + marriage);
    }
}
profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글