생성자
모든 클래스에는 생성자가 반드시 존재해야하며 하나 이상 가질 수 있다.
Cafe cafe = new Cafe();
new 연산자에 의해 생성자 실행한다. 생성자를 실행시키지 않고는 객체 생성은 불가능
생성자는 클래스로부터 객체를 생성할때 '객체의 초기화' 를 해준다.
* 객체 초기화란 변수를 초기화하거나 메서드를 호출하여 객체를 사용할 준비를 하는 것
- 기본생성자
클래스 내부에 기본 생성자 생성
객체를 새로 생성할때 가장 먼저 호출되는 메서드이며 반환값을 안 적어야 생성자로 인식한다.
클래스 내부에 기본 생성자 선언을 생략했다면 컴파일러는 {} 안에 내용이 비어있는 기본 생성자를 바이트 코드에 자동추가 시킨다 (선언한 생성자가 한개라도 존재하면 컴파일러는 기본생성자를 추가하지 않음)
또한 클래스의 접근제한자가 public없이 클래스가 선언됐다면 기본 생성자도 같이 public이 붙지 않는다.
[자바 소스 파일 Cafe.java]
public class Cafe() {
}
[바이트 코드 파일 Cafe.class ]
public class Cafe() {
//기본생성자
public Cafe() {
System.out.println("생성자.");
}
}
따라서 클래스 내부에 생성자 선언하지 않아도 new 연산자 뒤에 기본 생성자를 호출하여 객체를 생성한다.
Cafe cafe = new Cafe(); //Cafe() 기본생성자
생성자 선언 (생성자 명시)
Cafe 클래스에서 기본 생성자가 아닌 생성자를 명시적으로 선언하면? 아래의 형태로
근데 왜 public 를 안붙일까
public class Cafe() {
//생성자 명시
Cafe( 매개변수 선언,...) { // 생성자 블록
...
}
}
이렇게 클래스 안에 생성자가 명시적으로 선언을 했다면 선언된 생성자를 호출(new 연산자로 생성자 호출)하여 객체를 생성한다
Cafe cafe = new Cafe(); 기본생성자는 호출 불가
Cafe cafe = new Cafe("컴포즈", "espresso", "orangeJuice");
세개의 매개값은 생성자 블록내부에 전달
public class Cafe() {
// 생성자
Cafe(String name, String caffeine, String decaffeine) { //생성자 블록
this.name = name;
this.caffeine = caffeine;
this.decaffeine = decaffeine;
}
}
변수(필드) 초기화
필드를 선언할 때 초기값을 주게 되면 Cafe()클래스로부터 생성되는 객체는 모두 같은 데이터를 갖는다.
객체 생성 시점에는 같은 필드값이고 객체생성 후 변경가능
public class Cafe() {
String name = "컴포즈";
String caffeine;
String decaffeine;
}
Cafe cafe = new Cafe(); // name 필드값 = "컴포즈"
객체 생성 시점에서 외부에서 제공되는 값들로 초기화 해야한다면 생성자를 초기화 해준다
외부에서 제공되는 값 = 매개값으로 다양한 값들을 받아서 초기화 해주기
public class Cafe() {
String name = "컴포즈";
String caffeine;
String decaffeine;
public Cafe(String caf, String decaf){
this.caffeine = caf;
this.decaffeine = decaf;
}
}
Cafe cafe = new Cafe("Americano","blueberryJuice");
매개변수 cad , decaf을 통해 caffeine, decaffeine 값을 받는다.
원래는 필드(caffeine)와 매개변수(caf)가 동일한 이름을 사용한다
위처럼 하면 내부에서 필드에 접근 할 수 없어서 'this.필드명' 으로 하면 필드에 접근이 가능하다
접근을 못하는 이유 > 매개변수가 사용 우선순위가 높기 때문.
public class Cafe() {
public String name = "컴포즈";
public String caffeine;
public String decaffeine;
public Cafe(String caffeine, String decaffeine){
this.caffeine = caffeine; // this.caffeine (필드), caffeine (매개변수)
this.decaffeine = decaffeine; // this.decaffeine (필드) , decaffeine (매개변수)
}
}
this 객체 자신을 참조한다는 의미
이렇듯 중요한 몇개의 필드만 매개변수에 의해 초기화가 되고 나머지 필드는 필드 선언시 초기화하기도 한다.
생성자 오버로딩
오버로딩이란? 매개변수를 달리하는 생성자를 여러개 선언이 가능하다
자바는 생성자 오버로딩을 제공함으로써 객체생성을 다양한 방법으로 할 수 있다
외부에서 제공되는 다양한 데이터들을 이용해 객체를 초기화해야해서 생성자도 다양화 할 필요가 있다.
-아래는 생성자 오버로딩
public class Cafe {
//생성자 선언
Cafe() {
}
Cafe(String name, String caffeine) {
this.name = name;
this.caffeine = caffeine;
}
Cafe(String name, String caffeine, String decaffeine) {
this.name = name;
this.caffeine = caffeine;
this.decaffeine = decaffeine;
}
-다양한 방법으로 객체 생성
Cafe cafe = new Cafe(); // 기본생성자로 객체 생성
Cafe cafe = new Cafe("컴포즈", "espresso"); // Cafe(String name, String caffeine) 생성자 호출
Cafe cafe = new Cafe("컴포즈", "espresso", "orangeJuice"); // Cafe(String name, String caffeine, String decaffeine) 생성자 호출
new 연산자로 생성자를 호출할 때 제공되는 매개변수의 타입과 개수에 의해 호출될 생성자가 결정된다.
다시 정리
아래 예시는 다양한 Coffee 객체가 생성하고 생성자가 오버로딩 되어 있는 경우 new 연산자로 생성자를 호출 할때 매개변수의 타입과 개수에 의해 생성자 선택
public class Coffee {
String name = "Americano";
String bean;
int shot;
public Coffee() {
}
public Coffee(String bean) {
this.bean = bean;
}
public Coffee(String bean,int shot) {
this.bean = bean;
this.shot = shot;
}
public static void main(String[] args) {
//다양한 Coffee 객체가 생성
Coffee coffee1 = new Coffee();
System.out.println("coffee1 : " + coffee1.name);
Coffee coffee2 = new Coffee("아라비카");
System.out.println("coffee2 : " + coffee2.name + ", " + coffee2.bean);
Coffee coffee3 = new Coffee("케냐",2);
System.out.println("coffee2 : " + coffee3.name + ", " + coffee3.bean + ", " + coffee3.shot);
}
}
※ 주의 할 점
매개변수 순서가 바뀌면 안된다
public Coffee(int shot, String bean)
Coffee coffee3 = new Coffee("케냐",2);
package com.example.demo;
public class Cafe {
//멤버 변수
public String name;
public String caffeine;
public String decaffeine;
//생성자 선언
// public Cafe(String name, String caffeine, String decaffeine) {
// this.name = name;
// this.caffeine = caffeine;
// this.decaffeine = decaffeine;
// }
//기본 생성자
//생성자를 가장 먼저 호출되어 출력된다, 반환값을 안적으면 생성자로 인식
public Cafe() {
System.out.println("생성자.");
}
public void buy() {
System.out.println("메서드.");
}
public static void main(String[] args) {
// Cafe cafe = new Cafe("컴포즈", "espresso", "orangeJuice");
//객체 생성
Cafe cafe = new Cafe();
cafe.name = "Compose";
cafe.caffeine = "espresso";
cafe.decaffeine = "orangeJuice";
//객체 호출
System.out.println("카페 이름 : " + cafe.name);
System.out.println("카페인 음료 : " + cafe.caffeine);
System.out.println("비카페인 음료 : " + cafe.decaffeine);
cafe.buy();
}
}
= 출력된 console 창
생성자.
카페 이름 : Compose
카페인 음료 : espresso
디카페인 음료 : orangeJuiced
메서드.
클래스의 객체가 생성되면 생성자가 호출
다음으로 (객체 호출)멤버 변수 값들을 출력
System.out.println("카페 이름 : " + cafe.name);
System.out.println("카페인 음료 : " + cafe.caffeine);
System.out.println("디카페인 음료 : " + cafe.decaffeine);
마지막으로 메서드 호출하면서 cafe.buy(); 프린트출력
'공부' 카테고리의 다른 글
다형성 (0) | 2023.06.22 |
---|---|
접근 제한자 | 지역변수, 전역변수와 static (0) | 2023.06.22 |
메소드화 | 객체화 | 인스턴스 (0) | 2023.06.16 |
메소드 (1) | 2023.06.16 |
[백준] 4단계 | 10807, 10871, 10818, 2562, 5597, 3052, 1546 (0) | 2023.03.04 |