본문 바로가기
  • 시 쓰는 개발자
프로그래밍 문법/Java

6장 객체지향 (5) 오버로딩 , 생성자 , this , this() , 변수 초기화

by poetDeveloper 2024. 3. 10.

JAVA의 정석 강의를 들으며 공부하며 정리했습니다. 너무 자잘한 내용은 안적었습니다.

 

[자바의 정석 - 기초편] ch6-30,31 오버로딩

오버로딩 (overloading, 과적합)

한 클래스 안에 같은 이름의 메소드를 여러개 정의하는 것. 이름이 같다는 것은 하는 일이 같다는 것이다.

Ex) 프린트문을 생각. println()println(char x), println(int x) 등 매개변수에 따라서 여러 형태이다.

오버로딩이 성립하기 위한 조건

  1. 메소드 이름이 같아야 한다.
  2. 메소드끼리 매개변수의 개수 또는 타입이 서로 달라야한다. (반환 타입은 상관 없다.)

[자바의 정석 - 기초편] ch6-32~35 생성자, 기본 생성자

생성자

인스턴스 생성때마다 호출되는 인스턴스 초기화 메소드이다. 객체 만들 때 iv 초기화를 더 직관적이고 편하게 하기 위해 사용함.  ex)  Time t = new Time(12, 34, 56);

기본 생성자

클래스에 생성자가 1개도 없을 때만 컴파일러가 자동으로 매개변수가 없는 기본 생성자를 추가해준다. 컴파일러가 자동으로 만들어준다고는 하지만 우리가 직접 기본 생성자를 만들어주는 것이 좋다. 만약 사용자가 추가한 생성자가 있다면 컴파일러는 기본 생성자를 추가해주지 않음.

생성자 규칙

  1. 생성자 이름은 클래스 이름과 같아야한다.
  2. 리턴값이 없다. (void 안붙임)
  3. 모든 클래스는 기본 생성자를 포함해서 반드시 1개 이상의 생성자를 가져야한다.

[자바의 정석 - 기초편] ch6-36,37 생성자 this(), 참조변수 this

생성자 this()

같은 클래스내의 생성자에서 다른 생성자를 호출할 때는 서로 이름이 겹치므로 this()를 사용한다. this()쓰려면 생성자의 첫 번째 줄에서만 사용 가능하다.

this()를 쓰는 이유

한마디로 코드의 중복을 제거하기 위함이다. 생성자가 다음과 같이 2개 있다고 치자.

  • 특별한 요구가 없을 때 디폴트 값들로 초기화하는 기본생성자
  • 값들을 매개변수로 받아서 초기화하는 생성자

그런데 기본 생성자에서도 기본값들로 초기화하는 작업이 있기 때문에 두 생성자는 코드상 겹치게 된다. 따라서 값을 받아서 초기화하는 생성자를 기본 생성자에서 호출하여 코드의 낭비를 줄일 수 있다. 아래 예시를 보자.

class Car {
	String color;
	String gearType;
	int door;
	
	Car() { 
		this(“black”, “auto”, 4);
		// 원래라면 아래 3줄처럼 초기화해야하는데 다른 생성자와 코드 중복됨.
		// 따라서 this로 다른 생성자 호출하여 코드 중복 제거함
		// color = “black”;
		// gearType = “auto”;
		// door = 4;
	}

	Car(String c, String g, int d) {
		color = c;
		gearType = g;
		door = d;
	}
}

참조변수 this

참조변수 this인스턴스 자신을 가리키는 참조변수이다. this에는 인스턴스의 주소가 저장되어 있다. 생성자 this()와 전혀 다른 것이니 잘 구분하자. this는 참조변수, this()는 생성자이다. 참조변수 this는 인스턴스 메소드에서 사용 가능하다. 지역변수와 인스턴스 변수를 구별할 때 사용한다. 바로 위 예시를 가져와서 보자.

Car(String c, String g, int d) {
	color = c;
	gearType = g;
	door = d;
	// color, gearType, door는 인스턴스 변수이고 c, g, d는 지역변수이다.
}

여기서 지역변수와 인스턴스 변수가 한눈에 구별되지 않으므로 this를 활용할 수 있다. 물론, 여기 예시처럼 인스턴스 변수와 지역변수의 이름이 서로 다르다면 this를 생략할 수 있다. 그래서 인스턴스 변수의 진짜 이름은 this가 붙어있는 형태이다. class test { int x, y; } 라고 하면 사실 this.x , this.y 인 것인데 생략한 것이라고 보면 된다. 하지만 아래 예시처럼 인스턴스 변수와 지역 변수의 이름이 서로 같다면 this를 붙여서 구별해줘야한다.

Car(String color, String gearType, int door) {
	this.color = color;
	this.gearType = gearType;
	this.door = door;
	// this가 붙은 쪽은 인스턴스 변수, 안붙은 쪽은 지역변수이다.
}

 

주의) static 메소드는 객체를 생성하지 않기 때문에 iv를 사용할 수 없고, this도 사용할 수 없다. this는 생성자와 인스턴스 메소드에서 사용 가능하다.

[자바의 정석 - 기초편] ch6-38~41 변수의초기화, 멤버변수의 초기화

멤버변수(iv, cv)0으로 자동 초기화되고, 지역변수는 수동 초기화를 해줘야한다.

class Test {
	int x;
	int y = x; // 자동 초기화라서 가능함.

	void test11() {
		int i; // 값 모름
		int j = i; // 에러. 지역변수는 자동 초기화 안돼서 수동 초기화 해줘야함.
	}
}

지역변수는 메소드가 호출되어 작업하는 동안만 존재하기 때문에 생명주기가 짧다. 그래서 호출 스택은 재사용이 자주 되는데, 그때마다 지역변수를 0으로 초기화하는 작업을 한다면 성능이 떨어지기 때문에 자동 초기화를 하지 않는다. 그래서 지역변수는 0으로 초기화하지 않고 해당 메모리를 새로운 값으로 덮어씌우는 방식을 사용한다. 그에 반해 인스턴스 변수는 지역변수에 비해 오래 남아있기 때문에 0으로 자동초기화하고 사용할 수 있다.

멤버변수(iv, cv)의 초기화 방법 3가지

1. 자동 초기화 : 0으로 초기화

 

2. 간단 초기화 : 대입 연산자(=) 이용한 명시적 초기화

  • 기본형 변수의 초기화 : int a = 4;
  • 참조형 변수의 초기화 : Apple a = new Apple();

3. 복잡 초기화 (초기화 블록)

  • 인스턴스 초기화(iv) : 생성자 이용 (인스턴스블럭{ }을 사용할 수도 있지만 안쓰니 굳이 기억 X)
  • 클래스 초기화(cv) : static { }

초기화 시점

  • cv 초기화 시점 : 클래스가 처음 메모리에 로딩될 때 딱 1번 초기화
  • iv 초기화 시점 : 인스턴스가 생성될 때마다 초기화

초기화 순서

  • cv하고 → iv초기화
  • 자동초기화 → 간단초기화 → 복잡초기화