본문 바로가기

국비과정/JAVA

20230616 _[11일차]_02. 기본생성자 & 명시된생성자 & this

[ 생성자 ]

생성자란 클래스가 객체화 되어질 때 실제 객체를 생성해주는 코드입니다.

 

생성자는 그 외에도 아래와 같은 일을 합니다.

1. 클래스의 객체 생성

2. 멤버필드 초기화

3. 필요에 따라서 초기화 메소드 실행

 

위 내용을 다시 정의하면 생성자가 없다면 인스턴스를 발생시킬 수 없습니다.

 

생성자의 형식

생성자는 메소드와 유사한 형식을 가지고 있습니다.

하지만 메소드와 기능적인 부분에서 차이가 있습니다.

 

1. 생성자의 이름은 반드시 클래스명과 같아야 합니다.

만약 다르다면 메소드로 인식합니다. __ 소문자로 시작하면 메소드로 인식

 

2. 메소드가 아니기 때문에 리턴타입이 없습니다.

 

기본 생성자 (Default Constructor)

자바에서는 모든 클래스마다 컴파일 할 때 기본 생성자를 넣어줍니다.

단, 클래스에 생성자가 하나라도 있다면 제공되지 않습니다.

즉, 프로그래머가 생성자를 만들지 않았다면 자바가 제공해주는 생성자.

 

기본 생성자란

파라미터(매개변수)가 없는 생성자이고

이를 이용해서 생성된 인스턴스를 기본객체라고 합니다.

또한 모든 필드의 값은 기본값으로 초기화 됩니다.


[ 기본생성자 및 메소드 구분 ] 

 

package human;

public class Car {
	String name;
	// 필드
	
	// 생성자 : 클래스명과 동일, 대문자로 시작, 리턴 타입X	
	public Car() {	// 기본 생성자 : 없는 경우 자바가 만들어서 넣어줍니다.(파라미터 없음)
		System.out.println("인스턴스를 만듭니다");
	}
	
	// 메소드
	public void car() {
		System.out.println("car메소드 입니다.");
	}
	
	
	
	class Cat {
		public Cat() {	// --> 자바가 보고 있다가 기본 생성자를 주입
			
		}
	}
	
	
	public static void main(String[] args) {

		Car c = new Car();  // --> 선언하면 자바가 보고 있다가 기본 생성자를 주입
		c.car();	// car메소드 입니다.
		
	}
}

[ 명시된 생성자로 객체생성 ]  _ 파라미터가 들어가면 기본생성자는 생성되지 않음

 

package human;

class Mini {
	int age;

	public Mini(int age) { 
		System.out.println("객체가 생성됩니다. 초기는 " + age + "살입니다.");
	}
}


public class Car {
	public static void main(String[] args) {

		Mini m = new Mini(3);
				
	}
}

객체가 생성됩니다. 초기는 3살입니다.

** 주의 **

package human;

class Mini {
	int age;

	public Mini(int age) { // 파라미터**
		System.out.println("객체가 생성됩니다. 초기는 " + age + "살입니다.");
	}
}


public class Car {
	public static void main(String[] args) {

		Mini m = new Mini();	// Error : 명시된 생성자(파라미터 존재)여서
					// 객체 생성시에도 타입 맞춰서 파라미터 넣어줘야함.
	}
}

생성자를 만들기만 한거면 기본생성자 형태로, 

생성자를 만들면서 동시에 실행시키려면 명시된 형태로!!


[ this & this() ]

 

this.변수      // 내 변수 _ 내부(자기자신)용도, 해당 생성자 외부에서는 사용안됨.
this();           // 내 생성자()
super.변수   // 부모의 변수
super()        // 부모의 생성자()

 

package human;

class Cat{
	String name;
	int age;
	
	public Cat (String name) {
		System.out.println(name + "(이)가 태어났습니다.");
		System.out.println("Meww");
		this.name = name;	// this = 내 객체,  참조 변수 필드를 사용
	}

	public Cat (String name, int age) {
		this.name = name;
		if(age < 0) {
			age = 0;
		}
		this.age = age;
	}	
}


public class Car {
	public static void main(String[] args) {

		Cat c = new Cat("R2D2", -1);
		System.out.println(c.name);
		System.out.println(c.age);
				
	}
}

** static이 있는 메소드에서는 this. 쓸수 없음


R2D2
0

( 출력메소드 따로 생성 ) _ 메인메소드에서는 실행만!

 

Class Cat

        > public Cat (String name_ 이름출력 생성자

        > public Cat (String name, int age_ 이름 & 나이출력 생성자

       

        > void print () _ 이름 & 나이출력 메소드

package human;

class Cat{
	String name;
	int age;
	
	public Cat (String name) {
		System.out.println(name + "(이)가 태어났습니다.");
		System.out.println("Meww");
		this.name = name;	// this = 내 객체,  참조 변수 필드를 사용
	}

	public Cat (String name, int age) {
		this.name = name;
		if(age < 0) {
			age = 0;
		}
		this.age = age;
	}	
	
	void print() {
		System.out.println(this.name);
		System.out.println(this.age);
	}
	
	
}


public class Car {
	public static void main(String[] args) {

		Cat c = new Cat("R2D2", 3);
	
		c.print();	// 메소드 실행만!!
        
	}

}

R2D2
0

( 생성자역할 이해하기!!! ) _ 필드값 초기화, 객체생성

package jun19;

class Cat {
	String name;
	int age;
	
	public Cat(String name) {		// 생성자1
		System.out.println(name + "가 태어났습니다.");

	}
	
	public Cat(String name, int age) {	// 생성자2
		System.out.println(name + "가 태어났습니다. 나이는 " + age + "살입니다.");

	}
	
}


public class study {
	public static void main(String[] args) {

		Cat c = new Cat("Nabi");	// 생성자1을 호출하여 객체생성
		System.out.println(c.name);
		
		Cat c2 = new Cat("Nabe", 1);	// 생성자2를 호출하여 객체생성
		System.out.println(c2.name);	
		System.out.println(c2.age);
		
		
	}

}

Nabi가 태어났습니다.	// 생성자1객체생성 + 동시에 name값 초기화
null		// 하지만 객체의 name값 자체는 비어있음(초기값 = null)

Nabe가 태어났습니다. 나이는 1살입니다.	// 생성자2객체생성 + 동시에 name, age값 초기화
null	// 하지만 객체의 name값 자체는 비어있음(String초기값 = null)
0	// 하지만 객체의 age 자체는 비어있음(int초기값 = 0)

package jun19;


class Cat {
	String name;
	int age;
	
	public Cat(String n) {
		System.out.println(n + "가 태어났습니다.");
		this.name = n;		// 파라미터로 받는 n값을 생성자1의 name값으로 지정
	}
	
	public Cat(String n int a) {
		System.out.println(n + "가 태어났습니다. 나이는 " + a + "살입니다.");
		this.name = n;		// 파라미터로 받는 n값을 생성자2의 name값으로 지정
		this.age = a;		// 파라미터로 받는 a값을 생성자2의 age값으로 지정
	}
	
}


public class study {
	public static void main(String[] args) {

		Cat c = new Cat("Nabi");
		System.out.println(c.name);
		
		Cat c2 = new Cat("Nabe", 1);
		System.out.println(c2.name);
		System.out.println(c2.age);
		
		
	}

}

파라미터로 받는 값들을 생성자1 , 생성자 2 의 name, age값이 되도록 this를 사용해서 설정해줌


Nabi가 태어났습니다.
Nabi
Nabe가 태어났습니다. 나이는 1살입니다.
Nabe
1

 


 

( 생성자 만들고 다른파일에서 불러오기 )

 

package human;

public class Human {

	int age;
	String name;
	
    // 객체 생성용도로만 사용!!!! 메서드랑 다름
	public Human(String name1) {	
		name = name1;
	}
	public Human(int age1) {
		age = age1;
	}
	public Human(int age1, String name1) {
		age = age1;
		name = name1;
	}
    
}
  
  	public static void main(String[] args) {
    ...
    
    }

package human;

.....

public class Car {
	public static void main(String[] args) {

//		위에서 만들어준 생성자에 파라미터 있음(기본생성자 아님) 
//		기본생성자로 만들어진 인스턴스 = 기본 객체
//		Human h = new Human();  	// *Error : 파라미터 넣어줘야함

		Human h = new Human("홍길동");	// String 타입 파라미터 필요 
		Human h2 = new Human(0);
		Human h3 = new Human(150, "홍길동");
		
//		h.name = "홍길동";  --> 이제 요건 필요없음       
// 		Human 클래스에서 인스턴스 변수(age, name)선언 후 여기에서 값 넣어줄 필요없이    
//		생성자를 이용하면 생성하는 동시에 값을 넣을수 있음!!!!!!	
    }

}

 

(각 생성자에 의해 만들어진 인스턴스에서 가지고 있는 값)

* h    ==> 이름            -- public Human(String name1)

* h2  ==> 나이            -- public Human(int age1)

* h3  ==> 이름&나이   -- public Human(int age1, String name1

 


[ this ( ) ]

 

class Dog

    > public Dog(String name)  _생성자1 

    > public Dog(String name, int age) _생성자2

    > public Dog(String addr, String name, int age) _생성자3

 

    > public void sleep() { ... }  _ 메소드

package human;
//Dog 클래스를 만들어주세요
//생성과 동시에 이름과 나이를 지정하는 생성자를 만들어주세요
//메인 메소드에서 인스턴스를 발생시키시고 출력해주세요

class Dog {
	
	String name, addr;
	int age;
	
	// this();
	public Dog(String name) {
		this.name = name;
	}
	
	public Dog(String name, int age) {
		this(name);	// 생성자호출 -> (name)를 par.로 받는 생성자를 찾아감 (여기서는 생성자1)
		if(age < 0) {
			age = 0;
		}
		this.age = age;
		System.out.println(name + "가 태어났습니다. (" + age + ")살");
	}
	
	public Dog (String addr, String name, int age) {
		this(name, age);	// (name, age)를 par.로 받는 생성자를 찾아감 (여기서는 생성자2)
		this.addr = addr;
	}
	
	// 생성자 호출
	/*	같은 클래스에 정의된 다른 생성자를 호출하는 키워드 this();
	 * 	호출하려면 생성자의 파라미터의 순서에 맞게 호출하면 자동으로 호출됩니다.
	 * 
	 * 단 this생성자 호출은 생성자 첫줄에만 호출가능합니다.
	 * 호출은 단 한번만 가능합니다.
	 * 
	 */
	
	public void sleep() {
		System.out.println(this.name + "가 잠을 자요");
	}

}

public class Zoo {
	public static void main(String[] args) {
		Dog d1 = new Dog("강아지");
		Dog d2 = new Dog("Poppy", 5);
        
		d1.sleep();
	}

}

A : Dog (생성자2)에서 this(name); 으로 생성자1을 호출.
--> 생성자1의 name을 찾아 this.name = name; 실행.
--> 다시 생성자 2로 돌아와 다음 코드인 if ( age < 0 ) ~~ 실행.

 

Dog (생성자3)에서 this(name, age); 으로 생성자2를 호출. _ (파라미터 순서 맞춰줘야함)**

--> 생성자2의 name, age  찾아 this(name); &  this.age = age; 실행. 

                                                  A과정 실행
--> 다시 생성자 3로 돌아와 다음 코드인  this.addr = addr; 실행.


Poppy가 태어났습니다. (5)살
강아지가 잠을 자요

책 p. 245 _ 3번문제 풀어보기