javaboiii의 JAVA/JAVA 요약정리(멘토씨리즈)

JAVA -9)생성자

javaboiii 2024. 7. 20. 17:42

JAVA

1. 생성자의 특징

생성자란

클래스를 구성하는 구성요소 중 하나인 생성자는 객체를 생성할 떄 호출되어 객체의 초기화를 담당하는 특별한

메서드입니다. 객체를 생성하고 초기화하기 위해서는 반드시 생성자를 호출해야 합니다. 따라서 객체를 생성해야

하는 라이브러리용 클래스는 모두 생성자를 가지고 있습니다.

 

클래스 ==> 생성자 ==> 객체 생성

 

생성자는 일반 메서드와 달리 반환 타입이 없으며, 메서드 이름은 클래스 이름과 동일합니다.

생성자의 기본 구조는 다음과 같습니다.

클래스명(매개변수1, 매개변수2...){

}

생성자의 호출 위치

일반 메서드들과는 다른게, 생성자는 호출할 수 있는 곳이 정해져 있습니다. 생성자는 클래스를 기반으로 객체를 생성할 때

객체의 초기화를 담당하는 역할을 하므로 객체를 생성할 때만 호출할 수 있습니다.

생성자 호출 방법

생성자를 호출할 때는 new 키워드를 함께 사용합니다.

new 키워드는 생성자와 함께 객체를 생성하는 중요한 역할을 하는 연산자입니다.

 

생성자를 통해 객체를 생성하는 방법은 다음과 같습니다.

클래스명 객체명 = new 클래스명();

new 클래스명(); 이 메서드가 생성자입니다.

 

객체의 필드에 데이터를 삽입하고 메서드를 사용하기 위해 생성자를 통해 객체를 생성하고 사용할 준비를 합니다.

기본 생성자

자바의 모든 클래스에는 하나 이상의 생성자가 정의되어 있어야 하지만, 클래스를 생성하면서 개발자가 직접 생성자를

선언하지 않아도 자바 컴팡일러가 기본 생성자를 자동으로 제공해 줍니다. 다만 컴파일러의 눈에만 보일 뿐

코드에는 생략되어 있습니다.

 

직접 생성자를 선언하지 않으면 컴파일러가 생성자를 추가해서 객체 생성에 활용합니다. 이를 '기본 생성자'라고 합니다.

기본 생성자는 매개변수가 별도로 없으며, 중괄호{ } 블록 안에도 코드가 없는 비어있는 생성자를 말합니다.

기본 생성자는 개발자가 직접 생성자를 선언하지 않았을 때만 컴파일러가 자동으로 추가합니다.

만약 개발자가 직접 생성자를 선언한다면, 컴파일러는 선언된 생성자를 사용합니다.

생성자 선언 이유

생성자는 객체를 생성함과 동시에 객체를 초기화할 수 있습니다. 생성자를 통해 객체를 초기화한다는 것은

필드와 메서드를 호출하는 등 객체를 사용하기 위해 객체를 메모리에 올리다는 의미가 있습니다.

 

클래스 == 객체 초기화 ==> 메모리(객체)

 

생성자를 통해서 객체를 메모리에 올림과 동시에, 더 나아가 객체 멤버에 접근이 가능하므로 일반 메서드처럼 객체 멤버의

데이터를 초기화할 수도 있습니다. 이러한 이유로 직접 생성자를 선언하여 사용합니다.

메서드를 호출하면서 매개변수를 통해 값을 전달했던 것처럼 생성자 역시 매개변수를 통해 값을 전달할 수 있습니다.

 

생성자를 통해 필드를 초기화하면 필드에 접근하여 값을 주지 않아도 필으데 값이 들어갑니다.

생성자를 통한 필드 초기화

생성자를 통하지 않고 클래스에서 필드를 선언할 때 필드를 초기화할 수도 있습니다.

하지만 각각의 값이 다르다면 생성자를 통해 값을 전달하고 객체를 생성하는 것이 조금 더 효율적일 수 있습니다.

 

일반 메서드와 마찬가지로 매개변수는 생략할 수 있으며, 2개 이상 전달할 수도 있습니다.

2. 생성자 오버로딩

오버로딩(함수명 중복정의 허용)

생성자에 전달할 매개변수가 부족하면 객체를 생성할 수 없습니다. 선언된 생성자의 형태에 맞게 매개변수를 전달해 줘야 하기 때문입니다.

하지만 전달하는 갑을 이용하지 않고, 내부에서 선언된 필드의 기본값을 그대로 사용하고 싶었다면, 매개변수가 부족하다고 객체를 생성하지 못할 이유가 없을 것입니다. 이러한 경우를 해결하기 위해 자바는 생성자를 여러개 선언하는 것을

허용하고 있습니다. 상황에 따라 매개변수 없이 또는 1개, 2개 등 외부에서 제공할 수 있는 데이터만큼만 매개변수로 전달하여 객체를 생성할 수 있게 하는 방법입니다.

이렇게 생성자를 다양한 형태로 선언하는 것을 '생성자 오버로딩(constructor overloading)'이라고 합니다.

자바에서 오버로딩은 생성자에 국한되지 않고, 메서드에도 적용됩니다.

 

오버로딩은 단순히 개수의 차이에만 다양성을 제공하는 것은 아닙니다. 매개변수의 개수가 같을 때도,

매개변수의 자료형을 달리하여 오버로딩을 구현할 수 있습니다.

3. this 와 this()

this

변수 이름을 지을 때, 최대한 구체적이고 명확하게 작명하는 것이 보다 효율적인 코드를 작성하는데 도움이 된다는 것을 알고 있습니다. 그렇다면 매개변수에 대해서 다시 한 번 생각해 볼 필요가 있습니다. 클래스 필드를 명명할 때 이미 그 필드의

뜻을 내포하도록 작명하였기 때문에, 같은 뜻을 가지는 변수의 이름을 다르게 짓는 것은 논리적으로 모순일지도 모릅니다.

 

class Student{
	String name;
	int age;
    
    Student(Stirng n, int a){
    	name = n;
        age = a;
    }
}
혹은
class Student{
	String name;
	int age;
    
    Student(Stirng name, int age){
    	name = name;
        age = age;
    }
}

클래스 필드로 선언된 name, age는 보다 직관적으로 명명되어 있는 반면 매개변수 변수로 선언된 n이나 a는 어떤

의미의 변수인지 작성자만 명확히 이해할 수 있습니다.

 

이러한 상황을 해결하기 위해 this 키워드를 사용합니다.

this : 객체 자기 자신 스스로 참조

this 참조 변수는 인스턴스가 바로 자기 자신을 참조하는 데 사용하는 변수입니다. this를 필드에 붙여서 사용하면,

중괄호{} 안에서도 같은 이름의 매개변수와 필드를 구분해서 사용할 수 있습니다

this의 사용 방법은 다음과 같습니다.

this.필드 = 매개변수명;

Student 생성자 수정
class Student{
	String name;
	int age;
    
    Student(Stirng name, int age){
    	this.name = name;
        this.age = age;
    }
}

일반적으로 특정 필드에 값을 대입하기 위해 매개변수를 전달받는 경우, 필드와 같은 이름의 매개변수를 사용합니다.

this()

Phone(String brand, int series){
	this.brand = brand;
    this.series = series;
}

Phone(String brand, int series, String color){
	this.brand = brand;
    this.series = series;
    this.color = color;
}

매개변수를 2개 받는 생성자와 매개변수를 3개 받는 생성자는 사실 코드가 중복되고 있음을 확인할 수 있습니다.

중복되는 코드를 줄이기 위해 this()라는 메서드를 활용할 수 있습니다.

 

this(매개변수1, 매개변수2, ...)

this() 메서드를 사용하면, 다음과 같이 코드를 수정할 수 있습니다.

Phone(String brand, int series){
	this(brand, series);
}

Phone(String brand, int series, String color){
    this.brand = brand;
    this.series = series;
    this.color = color;
}

this() 메서드는 반드시 첫 줄에서만 사용할 수 있습니다.

응용문제

1. 다음 빈칸에 알맞은 단어를 작성해 보세요

  • 클래스의 이름과 동일하고 반환 타입이 없는 특별한 메서드를 ㅁㅁㅁ(이)라고 합니다.

정답 : 생성자

2. 다음 문장이 맞으면 O표, 틀리면X표 하세요.

  • 생성자를 호출할 때는 반드시 new 키워드를 사용해야 합니다 (  )
  • 매개변수가 1개인 생성자를 기본 생성자라고 부릅니다. (  )
  • 생성자를 코드로 명시하지 않으면 기본 생성자는 생략되어 있습니다. (  )

정답 : O X O

3. 다음 코드를 실행했을 때 콘솔창에 출력되는 결과는 무엇입니까 ?

package section09;

public class PRACTICE_09_03{
	public static void main(String[] args){
    	Computer computer1 = new Computer("banana");
        computer1.logo();
    }
}

class Computer{
	String brand;
    
    Computer(String name){
    	brand = name;
    }
    void logo(){
    	System.out.println("브랜드 : "+brand);
    }
}

실행 결과 : 
브랜드 : banana

4. 위 3번 코드에서 Computer 클래스의 brand 필드명을 name으로 변경한다면, 다음 빈칸에 들어갈 코드는 무엇입니까?

class Computer{
	String name;

	Computer(String name){
    	ㅁㅁㅁㅁㅁㅁㅁㅁ
	}
}

class Computer{
	String name;
    
    Computer(String name){
    	this.name = name;
    }
}

5. 다음 코드는 컴파일 에러가 발생합니다. 그 이유는 무엇이며, 어떻게 해결해야 할까요 ?

package section09;

public class PRACTICE_09_05{
	public static void main(String[] args){
    	Book b1 = new Book("어린왕자", 30);
        Book b2 = new Book();
    }
}

class Book{
	String title;
    int pages;
    
    Book(String title, int pages){
    	this.title = title;
        this.pages = pages;
    }
}

정답 : 
에러 이유
book 클래스의 생성자는 필드의 title값과 pages값을 강제하고 있지만
6번 라인에서 title값과 pages값을 넘겨주고 있지 않음

해결방법
Book b2 = new Book("해리포터",300);
생성자 호출시 값을 넘겨줌

'javaboiii의 JAVA > JAVA 요약정리(멘토씨리즈)' 카테고리의 다른 글

JAVA -11) 다형성과 타입 변환  (0) 2024.07.22
JAVA -10)상속  (0) 2024.07.21
JAVA -8) 메서드(Method)  (0) 2024.07.19
JAVA -7)클래스(Class)  (0) 2024.07.18
JAVA -6)배열  (0) 2024.07.17