생성자

  • 생성자란 객체를 생성할 때 호출하는 메소드 비슷한 것
  • 주로 일반 멤버변수의 초기화나 객체를 생성할 때 실행하는 작업을 정리
  • 생성자 형태
calss Person{
	String name;
    public Person(){
    	//생성자명은 클래스랑 동일
        name = "홍길동" //생성자의 역할은 멤버변수의 초기화
       }

특징

  • class명과 똑같아야됨
  • 객체생성시 딱 한 번 호출
  • 생성자도 오버로딩가능

 

생성자 VS void메서드 차이점

  • 형태가 retrun값이 없는 void메서드와 비슷하게 생겼다
  • 차이점 : 이름과 역할
    • 이름 : 생성자는 class명과 똑같아야하고 메서드는 달라야한다.
    • 역할 : 메서드는 다양한 기능을 담당하지만 생성자는 멤버변수의 초기화를 담당한다.




생성자를 왜 쓸까?

생성자는 자바창시자가 FM방식으로 설정했기때문이다.
자바 창시자는 생성자로 변수초기화시키고 메서드는 기능만 담당하도록 설정하고 싶었던 것이다!
자바 창시자가 정식방법으로 자바를 쓰길 원했지만 나는 한번도 쓴 적이 없는데 자바는 잘 돌아갔다.
어떻게 된 일일까?

  • 바로 아래 NEW에 답이 있다.




new의 역할

나는 생성자를 한번도 생성한 적 없이 java를 사용했는데 작동에 전혀 무리가 없었다.
왜 그럴까?

  • 바로 new 때문이다.
  • 별도의 생성자를 만들지 않았을 때 컴파일러에 의해 컴파일 타임에 자동으로 생성자가 만들어지기 때문이다. 이를 기본생성자라고 한다.
  • 기본생성자는 파라미터를 전달받지 않기 때문에 빈 객체를 생성한다.
  • 기본생성자의 형태
    • 생성자를 만들지않았지만 new라는 키워드를 통해서 BasicConstructor person = new BasicConstructor()를 통해서 자동으로 public BasicConstructor() {} 기본연산자가 생성된다.
public class BasicConstructor {

	String name;
	int age;
	boolean isHugry;
	
	//public BasicConstructor() {} //생략된 기본 생성자
	
	public static void main(String[] args) {
	
		//new연산자가  BasicConstructor()를 호출하면 컴파일러가 자동으로 기본생성자를 만든다
		BasicConstructor person = new BasicConstructor();
		
		//기본생성자이므로 외부에서 객체의 멤버 변수를 설정해줘야한다
		person.name ="홍길동";
		person.age =77;
		person.isHugry = false;
	}
}

 

this 키워드 용법

this에는 두가지 용법이 있다.

  1. this. : 현재 객체를 참조하기 위한 용도
  2. this() : 다른 생성자를 호출하는 용도




멤버변수를 참조하는 this.멤버변수명

현재 객체를 참조하기 위한 용도로 사용하는 this.먼저 보자.

아래 코드를 보자.
멤버변수명과 매개변수명을 동일하게 설정했다.
컴파일러가 첫번째 name과 두번째 name을 잘 구분할수있을까?

  • 참고 : 생성자자동생성단축키(Generate Constructor) : Alt + Shift + S → C
    • 매개변수로 만들고싶은 멤버변수의 체크박스를 틱하면 생성자를 생성해준다.
public class ThisPerson {
	
	String name;
	int age;
	boolean isHugry;
	
	ThisPerson(String name, int age, boolean isHungry){
		name = name; //컴파일러가 첫번째 name은 멤버변수로 두번째 name은 매개변수로 잘 구분할수있을까?
		age = age;
		isHungry = isHungry;
	}
}

 

정답은 NOPE! 구분하지못한다.
이때 구분해주기위해 멤버변수명앞에 this를 붙여준다.

 

 

public class ThisPerson {
	
	String name;
	int age;
	boolean isHugry;
	
	ThisPerson(String name, int age, boolean isHungry){
		this.name = name; 
		this.age = age;
		this.isHungry = isHungry;
	}
}

 

  • 이제 만든 생성자를 출력해보자.
    매개변수로 받은 this.name을 출력하는 코드이다.
 
public class ThisPerson {
	
	String name;
	int age;
	boolean isHugry;
	
	ThisPerson(String name, int age, boolean isHungry){
		this.name = name;
		this.age = age;
		this.isHugry = isHugry;
	}

	public static void main(String[] args) {
		ThisPerson person = new ThisPerson("홍길동", 20, true);
		System.out.printf("name : %s", this.name);
	}
}

 

홍길동이 출력될거라 기대했지만 출력값은 오류가 발생한다.

 

 

//위 코드 출력값
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Cannot use this in a static context

 

 

  • this는 객체에 대한 참조값이다.
  • this는 참조값이기때문에 객체가 생성되기 전에는 사용할 수 없다.
  • 따라서 static영역에서는 this키워드를 사용할 수 없다.

아래 코드를 출력하면 해결된다.

 

 

public class ThisPerson {
	
	String name;
	int age;
	boolean isHugry;
	
	ThisPerson(String name, int age, boolean isHungry){
		this.name = name;
		this.age = age;
		this.isHugry = isHugry;
	}
	
	String print(){
		return String.format("name : %s, age : %d", this.name, this.age);
	}
	
	public static void main(String[] args) {
		ThisPerson person = new ThisPerson("홍지민", 20, true);
		System.out.println(person.print());
	}
}

 

 

다른 생성자를 호출하는 this()

  • 파라미터를 다르게 해서 여러 개의 생성자를 정의하는 것을 생성자 오버로딩이라고 한다.
  • 메서드와 마찬가지로 생성자도 오버로딩이 가능하다.
  • 생성자오버로딩하는 이유 : 다른 생성자를 호출해서 중복코드를 제거.
    이때 다른 생성자를 호출하는 키워드가 this이다.

 

 

public class OverloadConstructorPerson {

	String name = "한사장";
	int age = 90;
	boolean isHugry = false;
	
	OverloadConstructorPerson(String name, int age, boolean isHungry){
		//아래 3줄의 중복코드가 발생함.
		this.name = name;
		this.age = age;
		this.isHugry = false;
	}
	
	OverloadConstructorPerson(String name, int age){
		//this()용법사용
		this(name, age, false);
	}
	
	OverloadConstructorPerson(String name){
		//this()용법사용
		this(name, 0, false);
	}
	
	OverloadConstructorPerson(){
		//아무 코드도 없으면 기존 멤버변수값이 출력된다.
	}
	
	public static void main(String[] args) {
		OverloadConstructorPerson p1 = new OverloadConstructorPerson("하지", 77);
		System.out.printf("이름 : %s, 나이 : %d%n", p1.name, p1.age);
		
		OverloadConstructorPerson p2 = new OverloadConstructorPerson("뽀니");
		System.out.printf("이름 : %s, 나이 : %d%n", p2.name, p2.age);
		
		OverloadConstructorPerson p3 = new OverloadConstructorPerson();
		System.out.printf("이름 : %s, 나이 : %d%n", p3.name, p3.age);
	}
}

//출력값
이름 : 하지, 나이 : 77
이름 : 뽀니, 나이 : 0
이름 : 한사장, 나이 : 90