자바 기본 배우기 -생성자란 무엇인가-

1. 생성자

 

인스턴스가 생성될 때 최초 한번 수행되는 함수

 

new 키워드와 함께 호출

 

클래스를 생성할 때 반드시 하나의 생성자를 호출

= 생성자는 여러개일 수 있다

 

성공적으로 실행되면 힙 영역에 객체 생성 후 객체의 주소가 리턴

 

필드의 초기화, 객체 생성 시 실행되어야 할 작업 작성

 

클래스 이름은 PascalCase로 작성하는 것이 관례이며, 생성자 이름은 클래스 이름과 동일하다

 

보니까 파이썬 __init__이랑 비슷함

 

2. 생성자의 특징

 

클래스와 이름이 대소문자도 모두 동일하다

 

반환타입이 없으며, void도 작성하지 않는다

 

필드의 초기화, 객체 생성 시 실행되어야 할 작업 작성

 

public class Dog {
    public Dog() {
        System.out.println("기본 생성자!");
        System.out.println("클래스 이름과 동일하고 반환타입이 없다");
    }
}

 

3. 기본 생성자(디폴트 생성자)

 

매개변수가 없는 생성자를 기본 생성자라고 부름

 

또한, 클래스 내에 생성자가 하나도 정의되어 있지 않다면, JVM이 자동으로 제공해준다.

 

형태는 매개변수가 없으며, 

 

클래스 명() {}

 

public class Dog {
    public Dog() {
        System.out.println("기본 생성자!");
        System.out.println("클래스 이름과 동일하고 반환타입이 없다");
    }
}

 

위의 Dog()는 사용자가 정의한 기본 생성자

 

그런데 만약에.. 다음과 같은 경우...

 

class Dog {
}

class Main {
    public static void main(String [] args) {
        //객체 생성
        
        Dog d = new Dog();
    }
}

 

Dog에 아무 생성자가 없는데?? 실행이 된다고??

 

JVM이 자동으로 Dog() {} 형태를 제공해줌

 

코드를 제공한다는 건 아니고.. jvm이 실행할때 Dog() { }가 있다고 생각하고 실행한다 이 소리겠지

 

class Dog {
    
    //JVM이 자동으로 제공
    Dog() { }
}

class Main {
    public static void main(String [] args) {
        //객체 생성
        
        Dog d = new Dog();
    }
}

 

4. 파라미터가 있는 생성자

 

생성자의 목적이 필드 초기화

 

필드?? 클래스가 가지고 있는 속성들.. String name, int age,....

 

그러므로 생성자 호출 시 값을 넘겨주어야 하며

 

이런 생성자를 작성하는 경우 JVM에서 기본 생성자를 추가하지 않는다

 

다음과 같은 경우..

 

class Dog {
    String name;
    int age;
}

class Main {
    public static void main(String[] args) {
        Dog d1 = new Dog();
        d1.name = "쫑";
        d1.age = 3;
    }
}

 

이런 경우에 JVM이 기본생성자를 제공해서...

 

class Dog {
    String name;
    int age;
    
    //JVM이 자동 제공
    Dog() { }
}

class Main {
    public static void main(String[] args) {
        Dog d1 = new Dog();
        d1.name = "쫑";
        d1.age = 3;
    }
}

 

d1.name = "쫑"; , d1.age = 3;으로 속성 변경 되는데..

 

class Dog {
    String name;
    int age;
    
    Dog(String n, int a){
        name = n;
        age = a;
    }
}

class Main {
    public static void main(String[] args){
        Dog d1 = new Dog();
        d1.name = "쫑";
        d1.age = 3;
        
        Dog d2 = new Dog("메리",4);
    }
}

 

Dog d2 = new Dog("메리",4);로 "메리"와 4를 각각 생성자의 String n, int a에 넘겨주어서...

 

d2가 name이 "메리", age가 4로 속성을 가지게 되는데

 

Dog d1 = new Dog();는 에러가 난다

 

왜냐하면 JVM이 기본생성자를 제공하지 않고.. 내가 정의한 생성자를 호출하기 때문에... 인자를 넘겨주지 않았다고 에러남

 

 

5. 생성자 오버로딩

 

클래스 내에 메소드 이름이 같고 매개변수의 타입 또는 개수가 다른 것

 

만약 위 상황에서 에러가 안날려면..?

 

Dog() {}를 정의해놓으면 에러나지 않는다

 

class Dog {
    String name;
    int age;
    
    Dog() { } //생성자 오버로딩
    
    Dog(String n, int a){
        name = n;
        age = a;
    }
}

class Main {
    public static void main(String[] args){
        Dog d1 = new Dog();
        d1.name = "쫑";
        d1.age = 3;
        
        Dog d2 = new Dog("메리",4);
    }
}

 

다음과 같이 여러개 생성자를 정의하면...

 

class Dog {
    Dog() { }
    
    Dog(String name) { }
    
    Dog(int age) { }
    
    Dog(String name, int age) { }
}

class Main {
    public static void main(String[] args){
        
        Dog d = new Dog();
        Dog d2 = new Dog("쫑");
        Dog d3 = new Dog(3);
        Dog d4 = new Dog("메리", 4);
    }
}

 

알아서 자기 자리 찾아서 잘 들어감...

 

 

6. this

 

참조변수로써 객체 자신을 가리킨다

 

this를 이용해서 자신의 멤버 접근이 가능하다

 

지역변수와 필드의 이름이 동일하면 필드임을 식별할 수 있게 해준다

 

객체에 대한 참조여서 static 영역에서 this는 사용할 수 없다

 

this.멤버변수로 객체 자기 자신이 가지는 변수를 가리킨다

 

자바스크립트의 this랑 비슷한듯

 

class Dog {
    String name;
    int age;
    void info() {
        System.out.print(name);
        System.out.println(age);
    }
}

 

위와 같이 써도 name, age를 알아서 찾기는 한데, 조금 더 명확하게 쓴다면

 

class Dog {
    String name;
    int age;
    void info() {
        System.out.print(this.name);
        System.out.println(this.age);
    }
}

 

다음과 같은 경우를 생각해보자..

 

class Dog {
    String name;
    int age;
    
    Dog(String name, int age){
    
        name = name;
        age = age;
    }
}

 

생성자의 name = name; age = age;를 JVM은 알아먹지 못한다.

 

하지만 this를 이용해서..

 

class Dog {
    String name;
    int age;
    
    Dog(String name, int age) {
        
        this.name = name;
        this.age = age;
    }
}

 

이러면 좌변의 this.name, this.age는 객체 Dog 자기 자신의 속성 name,age를 가리키고..

 

우변의 name, age는 인자로 넘어온 값을 가리켜서 JVM이 잘 할당시켜준다

 

 

--------------------------------------------------------------------------------------

 

this ([인자값..])으로 해당 객체의 생성자를 호출할 수 있다

 

생성자 내에서만 호출 가능하며, 생성자 내에서 첫번째 구문에 위치해야함

 

class Dog {
    String name;
    int age;
    
    Dog ( ) {
        Dog("쫑");
    }
    
    Dog (String name) {
        this.name = name;
    }
}

 

위와 같이 사용하면 Dog("쫑")에서 에러가 난다

 

하지만 다음과 같이 this("쫑");으로 바꾸면...

 

class Dog {
    String name;
    int age;
    
    Dog ( ) {
        this("쫑");
    }
    
    Dog ( String name) {
        this.name = name;
    }
}

 

JVM이 생성자 중에서 String 하나를 받는 생성자를 찾아서 알아서 실행시켜줌

 

그리고 이런 구문은..

 

"생성자 내에서만 호출 가능하며, 생성자 내에서 첫번째 구문에 위치해야함"

 

class Dog {
    String name;
    int age;
    
    Dog ( ) {
        this.age = 10;
        this("쫑");
    }
    
    Dog ( String name) {
        this.name = name;
    }
    
    Dog(int age){
        this.age = age;
    }
}

 

위와 같이..

 

this.age = 10;

this("쫑"); 하면 에러난다

 

 

TAGS.

Comments