37일차 - java (... vs [] , 패키지, this)

Yohan·2024년 4월 12일
0

코딩기록

목록 보기
53/156
post-custom-banner

... vs []

  • [] 는 필드나 로컬 변수에 선언 가능
  • ... 은 필드나 로컬 변수에 선언 불가능

...

  • ... 은 생성자나 함수등의 파라미터로만 선언이 가능
  • 가변인자이고 메서드내에서 가변인자는 배열로 처리
    // 생성자 파라미터로 가변배열을 받으면
    // main메서드에서 내가 넣고싶은 배열로 계속 초기화 가능
    // 단, 가변배열로 받아야하기 때문에 []는 들어올 수 없음
    StringList(String... initData) {
        sArr = initData;
    }
    
    // main
    
    // 초기 배열에 생성자에 전달한 데이터들이 들어있어야 함
    // 초기 배열에 어떤 배열이든 내가 원하는 것을 넣을 수 있음
        StringList hobbies = new StringList("안녕", "하이", "엥", "오잉", "또잉");
        hobbies.push("흐에");
        System.out.println("hobbies = " + hobbies.toString());

[]

  • 정적인 크기의 배열을 선언할 때 사용
    StringList(String[] initData) {
        sArr = initData;
    }
    
    // main
    // main메서드에서 특정 배열을 생성하여 생성한 객체에 넣어주어 사용
        String[] awef = {"하이", "바이", "뚜이"};
        StringList hobbies2 = new StringList(awef);
        System.out.println("hobbies2 = " + hobbies2);

...와 [] 예시

  • ...[] 를 이용하여 각각 생성자를 생성
  • main메서드에서 배열을 가변인자로 초기화하여 객체를 생성하는 경우 내가 원하는대로 입력해서 가능
  • 정적인 배열을 직접받아서 초기화해서 객체를 생성하는 경우 특정 배열을 생성하여 새로운 객체에 할당
public class ArrayExample {

    int[] numbers;

    // 배열을 가변 인자로 받는 생성자
    ArrayExample(int... nums) {
        numbers = nums;
    }

    // 배열을 직접 받는 생성자
    ArrayExample(int[] nums) {
        numbers = nums;
    }

    // 배열을 출력하는 메서드
    void printArray() {
        for (int num : numbers) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // 배열을 가변 인자로 초기화하여 객체 생성
        ArrayExample example1 = new ArrayExample(1, 2, 3, 4, 5);
        example1.printArray();

        // 배열을 직접 전달하여 객체 생성
        int[] nums = {6, 7, 8, 9, 10};
        ArrayExample example2 = new ArrayExample(nums);
        example2.printArray();
    }
}

패키지

비슷한 성격을 가진 자바 클래스나 인터페이스들을 모아 놓은 자바의 디렉토리

패키지의 특징

  1. 패키지를 만들어서 클래스를 배치하면, 클래스 최상단에 패키지 구문이 포함되게함
  2. 패키지 이름은 소문자 로 지어주는 것이 관례
  3. 상위 패키지와 하위 패키지를 구분할 때는 .(dot)을 사용
  4. 패키지 이름을 지을 때에는 식별자 규칙이 적용. 자바의 키워드는 패키지 이름으로 사용할 수 없으며, 특수문자($, _ 제외) 및 숫자로 시작하는 패키지 이름도 사용할 수 없음
  • 추가적으로 패키지가 다르다면 같은이름의 클래스를 수십, 수백개 만들 수 있음!!!
package day05.fruit;

public class Apple {

    public Apple() {
        System.out.println("fruit패키지의 사과입니다.");
    }
}



package day05.juice;

public class Apple {

    public Apple() {
        System.out.println("juice의 사과입니다.");
    }
}



// main
package day05;

// 다른 패키지에 있는 클래스를 로딩할 때 이름을 축약해서 쓰기위해 사용
import day05.juice.*;

import java.util.Scanner;

public class PackageMain {

    public static void main(String[] args) {
		// 이름을 줄일 수 없음 !!
        day05.fruit.Apple a1 = new day05.fruit.Apple(); // fruit
        day05.juice.Apple a2 = new day05.juice.Apple(); // juice
        new Banana();
        new Peach();

        Scanner sc = new Scanner(System.in);
    }
}

this

this란?

  • 현재 객체를 참조하는 키워드로, 클래스 내에서 자기 자신의 인스턴스 변수를 참조할 때 사용
    -> 메서드 내에서 로컬 변수와 인스턴스 변수를 구분할 수 있음
  • 현재 객체를 참조하는 키워드가 this이기 때문에 메서드를 사용하는 객체는 메서드 내에서 this이다. (아래 예시 참고)
public class Player {

    String name; // 닉네임
    int level; // 레벨
    int hp;    // 체력

    // 생성자
    Player() {
        System.out.println("1번 생성자 호출!");
	      name = "이름없음";
	      level = 1;
        hp = 50;
    }
		
		Player(String name) {
        System.out.println("2번 생성자 호출!");
	      name = name; //문제가 발생하는 코드
	      level = 1;
        hp = 50;
    }
		
	......

}

///////////////////////////////////////////////////////////////////

Player p2 = new Player("플레이어2");
System.out.println(p2.name); // null!;
  • 위 예시를 보게되면 필드의 name과 생성자의 매개변수 name이 이름이 동일하기 때문에 null이 발생하게 됨
    -> 필드에 this. 을 붙여서 필드와 생성자 매개변수와 구분해주면 된다.
Player(String name) {
    System.out.println("2번 생성자 호출!");
    this.name = name; //this가 가지는 주소값은 이 생성자를 부른 객체의 주소값이 된다. => 플레이어2를 생성했을 때는 p2
    level = 1;
    hp = 50;
}
///////////////////////////////////////////////////////////////////

Player p2 = new Player("플레이어2");
System.out.println(p2.name); // 플레이어2;

Player p3 = new Player("플레이어3");
System.out.println(p3.name); // 플레이어3;
  • this는 생성자나 메서드를 호출한 그 객체의 주소값과 동일한 주소값을 갖게됨
    -> p2를 통해서 Player 생성자를 호출했다면 생성자 내의 this는 p2가 가진 주소값을 띠게됨. 그렇기 때문에 this.name 은 곧 p2 주소값 객체의 name을 가리키게 되는 것
  • 마찬가지로 p3를 통해 생성자를 호출했다면 this는 p3가 가진 주소값을 띠게됨.

이러한 것이 가능한 이유?

  • 자바에서 클래스를 만들게되면 this라는 숨겨진 필드가 존재하기 때문이다. 그 this는 생성되는 객체의 주소값을 갖게 된다.

this. 예시

	// 생성자
    Player(String nickName) {
    	this.nickName = nickName;
    }

    // 메서드
    void attack(Player target) { // Player this 생략
        System.out.println("this = " + this);
        System.out.println("target = " + target);
        // 맞은 player가 체력을 10 감소시킴
        target.hp -= 10;
        // 때린 player의 체력을 3 감소시킴
        this.hp -= 3;

        System.out.printf("%s 님이 %s님을 공격했습니다.\n", this.nickName, target.nickName);
        System.out.printf("%s 님의 남은 체력: %d\n", this.nickName, this.hp);
        System.out.printf("%s 님의 남은 체력: %d\n", target.nickName, target.hp);
    }
    
    // main
    	Player parking = new Player("주차왕파킹");
        Player insultKing = new Player("욕설왕뻐킹");

        insultKing.attack(parking);

  • insultKing이 attack 메서드를 호출했기 때문에 attack 메서드 내에 this는 현재 insultKing을 가르킴 (this는 생략되어있어서 보이진않음)

this()

  • this. 을 통해서 나의 필드에 접근할 수 있었다. 여기서 더 나아가this() 를 통해서 생성자를 호출할 수 있다.
  • this() 를 사용하면 같은 클래스 내의 다른 생성자를 호출할 수 있다.
// 필드
    String nickName;
    int level;
    int hp;

    // 생성자: 객체가 만들어질 때 초기에 어떤값을 가질지를 정하는 곳
    // 생성자는 생성자 내부에서 또다른 생성자를 호출할 수 있음 -> this()
    public Player() {
        // this()로 다른 생성자를 부를때는 생성자당 1번씩만 가능
        // 그리고 가장 첫 줄에 써야 함
        this("이름없는캐릭터", 1, 50); // 4번 생성자 호출!
        System.out.println("1번 생성자 호출!");
    }

    Player(String nickName) {
        this(nickName, 1); // 3번 생성자 호출!
        System.out.println("2번 생성자 호출!");
    }

    public Player(String nickName, int level) {
        this("이름없는캐릭터", 1, 50); // 4번 호출
        System.out.println("3번 생성자 호출!");
    }

    public Player(String nickName, int level, int hp) {
        System.out.println("4번 생성자 호출!");
        this.nickName = nickName;
        this.level = level;
        this.hp = hp;
    }
    
	// main
    Player p1 = new Player("야미");
    System.out.println("p1 = " + p1);
  1. 2번 생성자가 호출
  2. this(nickName, 1); 가 가장 먼저 실행되면서 3번 생성자가 호출
  3. 3번 생성자에서 this("이름없는캐릭터", 1, 50); 가 호출되면서 4번 생성자 호출
  4. "4번 생성자 호출!" 이 출력되고 nickName, level, hp가 초기화
  5. 3번 생성자에서 "3번 생성자 호출!" 출력
  6. 2번 생성자에서 "2번 생성자 호출!" 출력

this() 특징

  • this()로 다른 생성자를 호출할 수 있는 것은 생성자당 1번
  • 가장 첫 줄에 작성해야함
profile
백엔드 개발자
post-custom-banner

0개의 댓글