본문 바로가기
BackEnd/JAVA

[JAVA] 클래스(class)와 생성자

by 성은2 2023. 1. 14.

Java의 기본 개념과 문법을 한번 더 정리했다. 

1. class란

객체를 생성하기 위한 필드와 메소드가 정의되어 있는 곳으로, 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(instance)라고 한다. 그리고 클래스로부터 객체를 만드는 과정을 인스턴스화 라고 한다. 

 

 

 

2. class 선언

사용하고자 하는 객체를 구상했다면 그 객체의 대표 이름을 하나 결정하고 이것을 클래스 이름으로 한다.

"클래스이름.java"로 소스 파일을 생성한다. 

 

Car.java

public class Car {

}

 

두 개 이상의 클래스가 선언된 소스 파일을 컴파일 하면 바이트 코드 파일은(.class) 클래스를 선언한 개수 만큼 각각 생성된다.

다만, 파일 이름과 동일한 이름의 클래스 선언에만 public 접근 제한자를 붙일 수 있다.

가급적이면 소스파일 하나당 동일한 이름의 클래스 하나를 선언하는 것이 좋다.

 

Car.java

public class Car {
}

class Tire { // public 접근 제한자x
}

 

 

new 연산자

new는 클래스로부터 객체를 생성시키는 연산자다.

new 연산자 뒤에는 생성자가 오는데, 생성자는 클래스() 형태를 가지고 있다. new연산자로 생성된 객체는 heap 영역에 생성되며, 객체의 주소를 리턴하도록 되어 있다.

 

 

예제로 Student 클래스를 생성하고, 사용.

 

Student.java

public class Student {
}

 

StudentExample.java

public class StudentExample {

	public static void main(String[] args) {
    	Student s1 = new Student();
        // s1 변수가 Strudent 객체를 참조
        
        Student s2 = new Student();
        // s2 변수가 또 다른 Student 객체를 참조
        
    }
}

s1과 s2가 참조하는 Student 객체는 완전히 독립된 서로 다른 객체다.

 

 

 

 

3. Class의 구성 멤버

필드(Field)

생성자(Constructor)

메소드(Method)

public class ClassName {

	//필드
    int fieldName;
    
    // 생성자 
    ClassName() {}
    
    // 메소드
    void methodName() {}
    
    }

 

* 필드 : 객체 고유의 데이터, 객체의 현재 상태 데이터를 저장하는곳.

선언 형태는 변수와 비슷하지만 필드를 변수라고 부르지 않음!

변수는 생성자와 메소드 내에서만 사용되고 생성자와 메소드가 실행 종료되면 자동 소멸된다.

하지만 필드는 생성자와 메소드 전체에서 사용되며 객체가 소멸되지 않는 한 객체와 함께 존재한다. 객체와 함께 존재한다는 말이 좋다. 뭔가 변수와 필드를 헷갈리지 않을 것 같음.

 

클래스 외부에서 사용할 경우 우선적으로 클래스로부터 객체를 생성한 뒤 도트(.) 연산자를 사용해 필드에 접근,사용 할 수 있다.

void method() {

	// 외부 클래스의 Car 객체 생성
    Car myCar = new Car();
    
    // 도트(.)로 접근해 필드 사용
    myCar.speed = 60;
 	/* 하지만 이렇게 외부에서 필드값을 변경하는건 어디에서 어떤 데이터의 변경이 일어났는지 알 수 없기 때문에
    유지보수 등 좋지 않기 때문에 지양함..
    */
    
}

 

 

 

* 생성자 : 클래스로부터 객체를 생성할때 호출되어 객체의 초기화를 담당한다.

new연산자와 같이 사용된다. 생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없다. new 연산자에 의해 생성자가 성공적으로 실행되면 heap 영역에 객체가 생성되고 객체의 주소가 리턴된다. 리턴된 객체의 주소는 클래스 타입 변수에 저장되어 객체에 접근할 때 이용된다.

 

  • 기본 생성자
    • 모든 클래스는 생성자가 반드시!! 존재하며, 하나 이상을 가질 수 있다. 우리가 클래스 내부에 선언을 생략했어도, 컴파일러가 {} 블록 내용이 비어있는 기본 생성자를 바이트 코드에 자동으로 추가 시킨다.

 

  • 생성자 선언
    • 클래스에 명시적으로 선언한 생성자가 한 개라도 있으면 컴파일러는 기본 생성자를 추가하지 않음.
    • 명시적으로 생성자를 선언하는 이유는, 객체를 다양하게 초기화 해서 사용하기 위해서임.
    • 생성자는 메서드와 비슷하게 생겼지만 리턴 타입이 없고, 클래스 이름과 동일함. 

 

public class Car {
	
    // 필드
    String category = "car"; // 외부에서 값을 매개변수로 주입받지 않는 경우
    String model;
    String color;
    int maxSpeed;
    
    
    /*
    * 문법
    * 클래스( 매개변수 선언,... ) {
    * 객체의 초기화 코드
    * }
    */

	// 명시적 선언 생성자, 관례적으로 필드와 동일한 이름을 갖는 매개변수 사용
    // 필드와 매개변수 이름이 동일하기 때문에 생성자 내부에서 해당 필드에 접근할 수 없음.
    // 해결 방법으로, 필드 앞에 this를 붙임(this : 객체 자신의 참조)
    Car(String model, String color, int maxSpeed) {
    	this.model = model;
        this.color = color;
        this.maxSpeed = maxSpeed;
        //     필드     매개 변수
    }
}

매개 변수는 new연산자로 생성자를 호출할 때 외부의 값을 생성자 블록 내부로 전달하는 역할을 한다.

 

 

 

 

클래스에 생성자가 명시적으로 선언되어 있으면 반드시 선언된 생성자를 호출해서 객체를 생성해야 함!

위와 같이 Car클래스에 매개변수를 가지는 생성자를 명시적으로 선언한 경우, 기본 생성자를 호출해서 객체를 생성할 수 없다.

public class CarExample {

	Car myCar = new Car("volvo", "pink", 3000);
	// Car myCar = new Car(); (x) <- 기본 생성자를 호출할 수 없음.

}

 

 

 

 

그런데.. 외부에서 제공되는 다양한 데이터로 객체를 초기화 시키고 싶을수 있다.

필요에 따라 주어진 정보가 없이 기본생성자로도 객체를 생성할 수도 있어야 한다. 그래서 자바는 다양한 방법으로 객체를 생성할 수 있도록 생성자 오버로딩(Overloading)을 제공한다.

 

 

 

 

생성자 오버로딩 : 매개변수를 달리하는 생성자를 여러 개 선언 하는 것.

매개변수의 타입, 개수, 순서를 다르게 선언하면 다양한 방법으로 객체를 생성해서 사용할 수 있게됨!

 

 

 

 

다른 생성자 호출 (this())

생성자를 여러개 만들어서 사용하다 보면, 필드 초기화 내용이 공통되는 부분 등의 중복코드가 발생 하게 된다. 이럴때 this()를 사용한다.

 

  1. this()는 자신의 다른 생성자를 호출 하는 코드
  2. 반드시 생성자의 첫줄에서만 허용됨.
  3. this()의 매개값은 호출되는 생성자의 매개 변수 타입에 맞게 제공해야 한다.
  4. this() 다음에는 추가적인 실행문이 올 수 있다.
  5. 즉 호출되는 생성자의 실행이 끝나면 원래 생성자로 돌아와서 다음 실행문을 진행한다.
public class Car {


	// 필드
    String model;
    String color;
    int maxSpeed;
    
    // 생성자
    Car() {
    }
    
    Car(String model) {
    	this(model, "은색", 250); // 호출
    }
    
    Car(String model, String color){
    	this(model, color, 250);
    }
    
    // 중복되는 코드인 필드 초기화 코드를 한 생성자에 집중적으로 작성
    Car(String model, String color, int maxSpeed){
    	this.model = model;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }

 

 

 

메소드 : 객체의 동작에 해당하는 부분. 메소드 호출시 해당 중괄호 블록에 있는 모든 코드들이 일괄적으로 실행된다.