본문 바로가기

자바스프링웹공부(2024)/자바

2024.08.27. 생성자, this

반응형

* 이클립스 : 생성자 자동 생성 단축키 : Alt + Shift + S -> O

 

* 생성자 :

- 클래스의 세번째 구성요소.(1. 멤버변수 인스턴스 생성 시 최초로 사용된다.

- 생성자는 인스턴스를 생성(new 객체)하면 호출된다. 
- 생성자를 아무것도 정의 하지 않으면 컴파일러에 의해 자동으로 기본 생성자가 생성됨.
- 기본생성자: 파라미터 없음,중괄호 블록내에 아무 코드도 없음 => 아무것도 전달받지 않으며,아무 작업도 수행하지 않음.

public class Ex1 {
	public static void main(String[] args) {
		new Person(); // 이거만 해도 생성자가 호출되면서 syso가 찍힌다.
	}
}

class Person {
    //멤버변수
    String name;
    int age;
    
    // 생성자 : new 할때(생성할때마다)마다 호출된다.
    // 기본생성자는 생략되어 있다. 없어도 있다고 보면됨.
    //만들자마자 데이터를 초기화 하고 싶을 때 사용함.
    public Person() { // => 이것이 바로 기본생성자!
    	System.out.println("생성자 호출됨");
    }
    //메서드
    public void showInfo () {
    	System.out.println("이름");
    }
}


 * 기본생성자를 수정해서 직접 만들었을 때는 기본생성자를 따로 만들어줘야 사용가능하다.

public class Ex1 {
	public static void main(String[] args) {
		new Person("홍길동", 20);
		Person p2 = new Person(); // (X) 지금 기본생성자가 없기때문에 사용못함.
        // 클래스의 인스턴스 생성시 기본 생성자를 호출하는 경우
        // => 기존에 파라미터를 전달받는 생성자를 정의해 놓은 경우
        // 컴파일러가 기본 생성자를 자동으로 생성하지 않으므로 기본 생성자 호출 코드가 존재하는 경우오류발생

        //밑에  기본생성자 새로 만들어서 사용가능함.
     }
}
class Person {
    //멤버변수
    String name;
    int age;
    // 생성자 오버로딩
    // 기본생성자 새로 만들기
    Person(){} // 기본생성자를 만들어 줘야 기본생성자 사용가능.
   	// 만들자마자 데이터를 초기화 하고 싶을 때 사용함.
    Person(String n, int a) {
        name = n;
        age = a;
    }
    //메서드
    public void showInfo () {
	    System.out.println("이름");
    }
}



* 생성자 오버로딩

- 파라미터가 다른 생성자를 여러번 정의하는 것

- 생성자 오버로딩 규칙 
  파라미터에 들어가는 데이터 타입이 같으면 안된다. ex) String 타입 파라미터는 순서를 바꿔도 오버로딩 안됨.
 타입이 겹치므로!! 변수명은 별칭에 불과하다. 
- 하지만 타입이 다르면 파라미터 순서를 바꿔도 된다.

 

Q. 생성자 오버로딩 후 사용하기 && 기본생성자 초기화 후 사용하기

class Account {
    // => 생성자 내에서 멤버변수를 다음과 같이 초기화
    //  계좌번호(accountNo): "111-1111-111"
    // 예금주명(ownerName): "홍길동"
    // 현재잔고(balance) : 10000

    
    String accountNo;
    String ownerName;
    int balance;
    // 기본생성자 초기화
    public Account() {
        accountNo = "111-1111-111";
        ownerName = "홍길동";
        balance = 10000;
	}
	// 파라미터 3개(계좌번호,예금주명,현재잔고)를 전달받아 초기화하는 생성자 정의
    public Account(String accountNo, String ownerName, int balance) {
        this.accountNo = accountNo;
        this.ownerName = ownerName;
        this.balance = balance;
    }
}

public class Test1 {
    public static void main(String[] args) {
        Account acc = new Account(); // 기본생성자를 초기화하여 바로 사용가능함.
        System.out.println(acc.accountNo);
        System.out.println(acc.ownerName);
        System.out.println(acc.balance);
        System.out.println("---------------------");
        Account acc2 = new Account("222-2222-222", "홍길순", 20000); // 생성자 오버로딩 후 직접 기입하여 사용가능함.
        System.out.println(acc2.accountNo);
        System.out.println(acc2.ownerName);
        System.out.println(acc2.balance);
    }
}

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

    // 반복문 사용하여 코드 줄이기
    Account2 acc1 = new Account2();
    Account2 acc2 = new Account2("222-2222-222");
    Account2 acc3 = new Account2("333-3333-333", "홍길순");
    Account2 acc4 = new Account2("444-4444-444", "이순신", 2000000);
    acc1.showAccountInfo();
    acc2.showAccountInfo();
    acc3.showAccountInfo();
    acc4.showAccountInfo();

    //반복문을 사용하여 위의 코드를 줄여보자!
    Account2[] arr = {acc1,acc2,acc3,acc4};
    for (int i = 0; i < arr.length; i++) {
    	arr[i].showAccountInfo();
    }
    // 향상된 for문을 사용하여 보자.
    for (Account2 i : arr) {
    	i.showAccountInfo();
    }

 



* this 키워드 

1. 레퍼런스(Reference) this
- 자신의 인스턴스 주소가 저장되는 레퍼런스(=참조변수)
- 개발자가 임의로 생성할 수 없으며, 인스턴스 생성 시 자동으로 주소가 저장됨.
       => 각 인스턴스 마다 this에 저장되는 주소가 달라짐. 
- 일반적인 참조변수와 동일한 방법으로사용가능 
- 주로 생성자나 메서드 내에서 멤버변수와 로컬변수의 이름이 동일할 경우.  멤버변수를 구별할 목적으로 사용
- 또한, 자신의 인스턴스 내의 다른 메서드를 호출하는데에도 사용가능
  (일반적으로 메서드 이름은 로컬 변수처럼 중복되지 않으므로 this 생략)

--------------------------				stack - heap---- 
Person p = new Person("홍길동", 20);	 //this - 100 
Person p2 = new Person("홍길동", 20);	 //this - 200
// this 값은 누가(p1인지 p2인지) 호출하는 지에 따라서 바뀐다.

Person p = new Person();
p.printThis(); // 똑같은 주소가 나온다.
System.out.println(p); // 똑같은 주소가 나온다.

Person p2 = new Person(); 
p2.printThis(); // 똑같은 주소가 나온다.
System.out.println(p2); // 똑같은 주소가 나온다.

Person p3 = p; // 이렇게 하면 사람(Person)은 2명이다. new가 2번 나왔기 때문에 
System.out.println(p3); // 이 주소는 p의 주소와 같은 것이 나온다. 
/* 하지만 p1과 p2의 주소는 다른 것이 나온다. */
// 객체가 몇개가 나올지 모르니까 this를 키워드로 붙인다.


class Person {
    // Person this; 요것도 기본생성자 처럼 인스턴스를 생성하면 만들어진다.
    String name;
    int age;

    public void printThis() {
    	System.out.println(this);
    } 
}

  
* 다른 생성자 호출: this()
• 생성자 오버로딩이 많아질 경우 생성자간 중복 코드 발생!
• 초기화는 하나의 생성자에만 집중적으로 작성한 후 나머지 생성자에서는 초기화 내용이 있는 생성자를 호출
• 생성자에서 다른 생성자를 호출할 때 this()사용

class Account2 {
    String accountNo;
    String ownerName;
    int balance;
    
    public Account2() {
        // accountNo = "111-1111-111";
        // ownerName = "홍길동";
        // balance = 0;

        //=> 다른 생성자를 호출하는 this()를 사용하면 코드가 짧아진다. 
        this("111-1111-111", "홍길동", 0);
    }

    public Account2(String accountNo) {
        // this.accountNo = accountNo;
        // ownerName = "홍길동";
        // balance = 0;
        this(accountNo, "홍길동", 0);
    }

    public Account2(String accountNo, String ownerName) {
        // this.accountNo = accountNo;
        // this.ownerName = ownerName;
        // balance = 0;
        this(accountNo, ownerName, 0);
    }

    public Account2(String accountNo, String ownerName, int balance) {
        this.accountNo = accountNo;
        this.ownerName = ownerName;
        this.balance = balance;
    }
}

 

반응형