Study/JAVA

[JAVA] 7장 - 클래스 내부 구성 요소(2)

오구민 2022. 10. 2. 17:30

클래스! 아주 길다!

그제 작성한 것을 이어 작성한다...

오늘도 공부 화이팅...

 

 

1. 생성자

1.1 생성자의 특징

생성자를 작성할 때 꼭 지켜야 하는 문법은 두 가지다.

첫 번째는 반드시 클래스명과 동일한 이름으로 지어야 한다. (클래스명과 다르면 더 이상 생성자가 아니다.)

두 번째는 메서드와 비슷한 구조를 지니고 있지만, 리턴 타입이 없다. 이는 void와는 전혀 다른 얘기다.

아래는 생성자의 문법구조다. 입력매개변수는 생략 가능하다.

클래스명(입력매개변수) {
}

 

1.2 기본 생성자의 자동 추가

7장(1)에서 A a = new A() 같이 생성자를 호출해 객체를 만든 적은 있지만 생성자를 만들진 않았다.

생성자를 만들지 않아도 객체가 생성됐던 이유는 생성자를 포함하지 않는 클래스에서 컴파일러가 기본 생성자를 추가해줬기 때문이다. 이때, 기본 생성자는 입력매개변수가 없는 생성자를 말한다.

생성자가 호출되는 것만으로 객체가 내부적으로 생성되는 것이다!

package study_class;

class A {
	int m; //초기값??
	void work() {
		System.out.println(m);
	}
	/*
	A() {
	
	}
	 */
}
class B {
	int m; //초기값??
	void work() {
		System.out.println(m);
	}
	B() {
		//기본 생성자를 직접 정의한 구간
	}
}
class C {
	int m;
	void work() {
		System.out.println(m); // 생성자로 넘어온 값
	}
	C(int a) {
		m = a; //입력매개변수로 전달된 값으로 필드 초기화
	}
}

public class Class_study {
	public static void main(String[] args) {
		//클래스의 객체 생성
		A a = new A(); //컴파일러가 자동으로 추가한 기본 생성자를 호출해 객체 생성
		B b = new B(); //직접 정의한 기본 생성자를 호출해 객체 생성
		//C c = new C(); //기본 생성자 호출 불가능
		C c = new C(3);
		
		//매서드 호출
		a.work();
		b.work();
		c.work();
	}
}

 

1.3 생성자와 객체의 생성 방법

생성자의 모양에 따라 객체를 생성하는 방법이 결정된다.

메서드처럼 생성자의 입력매개변수 자료형이나 개수에 따라 여러 개의 생성자를 정의할 수 있다.

package study_class;

class A {
	A() {
		System.out.println("첫 번째 생성자");
	}
	A(int a) {
		System.out.println("두 번째 생성자");
	}
	A (int a, int b) {
		System.out.println("세 번째 생성자");
	}
}

public class Class_study {
	public static void main(String[] args) {
		A a1 = new A();
		A a2 = new A(3);
		A a3 = new A(3, 5);
	}
}

 

 

 

2. this 키워드와 this() 메서드

클래스 외부에서 멤버를 호출하기 위해서는 객체를 먼저 생성한 후 '참조 변수명.멤버명'의 형태로 호출하지만, 클래스 내부에서는 객체의 생성 없이 필드와 메서드를 바로 사용할 수 있다고 한다.

하지만 모든 사용할 수 있는 상태의 멤버는 항상 객체 속에만 존재한다.

 

2.1 내부 객체 참조 변수명 this 키워드

모든 메서드에는 자신이 포함된 클래스의 객체를 가리키는 this라는 참조 변수가 있다.

원래 n이라는 변수를 사용하려면 this.n이라고 사용해야 하지만, 컴파일러가 자동으로 this.를 추가해준 덕에 클래스 내부에서 필드와 메서드를 그대로 사용할 수 있었던 것이다.

아래는 

package study_class;

class A {
	int m;
	int n;
	void init(int a, int b) {
		int c;
		c = 3; //얘는 무슨 값일까?
		this.m = a;
		this.n = b;
	}
	void work() {
		this.init(2,  3);
	}
}

public class Class_study {
	public static void main(String[] args) {
		// 클래스 객체 생성
		A a = new A();
		//메서드 호출/필드값 활용
		a.work();
		System.out.println(a.m);
		System.out.println(a.n);
	}
}

이 다음은 지역 변수명과 필드명이 동일할 때 this.로 명시적 구분하는 코드다.

package study_class;

class A {
	int m;
	int n;
	void init(int m, int n) {
		m = m;
		n = n;
	}
}
class B {
	int m;
	int n;
	void init(int m, int n) {
		this.m = m;
		this.n = n;
	}
}
public class Class_study {
	public static void main(String[] args) {
		// 필드명과 지역 변수명이 같고, this 키워드를 사용하지 않음
		A a = new A();
		a.init(2, 3);
		System.out.println(a.m);
		System.out.println(a.n);
		
		//필드명과 지역 변수명이 같고, this 키워드를 사용함.
		B b = new B();
		b.init(2, 3);
		System.out.println(b.m);
		System.out.println(b.n);
	}
}

 

2.2 클래스 내 다른 생성자를 호출하는 this() 메서드

이번에는 this() 메서드다.

this() 메서드는 자신이 속한 클래스의 내부의 다른 생성자를 호출하는 명령어다.

이를 구성할 때는 반드시 두 가지 문법적 규칙을 지켜야 한다.

첫 번째는 생성자의 내부에서만 사용할 수 있다는 점이고, 두 번째는 생성자의 첫 줄에 위치해야 한다는 점이다.

이 둘 중 하나라도 지켜지지 않으면 바로 오류가 발생한다.

package study_class;

class A {
	A() {
		System.out.println("첫 번째 생성자");
	}
	A(int a) {
		this();
		System.out.println("두 번째 생성자");
	}
	/* 메서드에서는 this() 메서드가 사용불가
	 * void abc() {
	 * 	this();
	 */
}
public class Class_study {
	public static void main(String[] args) {
		//객체 생성
		A a1 = new A();
		System.out.println();
		A a2 = new A(3);
	}

this() 메서드를 이용해 생성자의 중복을 제거하는 코드가 예제로 있었다.

package study_class;

class A {
	int m1, m2, m3, m4;
	A() {
		m1 = 1;
		m2 = 2;
		m3 = 3;
		m4 = 4;
	}
	A(int a) {
		m1 = a;
		m2 = 2;
		m3 = 3;
		m4 = 4;
	}
	A(int a, int b) {
		m1 = a;
		m2 = b;
		m3 = 3;
		m4 = 4;
	}
	void print() {
		System.out.print(m1 + " ");
		System.out.print(m2 + " ");
		System.out.print(m3 + " ");
		System.out.print(m4);
		System.out.println();
	}
}
class B {
	int m1, m2, m3, m4;
	B() {
		m1 = 1;
		m2 = 2;
		m3 = 3;
		m4 = 4;
	}
	B(int a) {
		this();
		m1 = a;
	}
	B(int a, int b) {
		this(2);
		m2 = b;
	}
	/* B() 생성자를 호출하고, 두 필드 값을 한 번에 수정할 수도 있다!
	 * B(int a, int b) {
		this();
		m1 = a;
		m2 = b;
	}
	 */
	void print() {
		System.out.print(m1 + " ");
		System.out.print(m2 + " ");
		System.out.print(m3 + " ");
		System.out.print(m4);
		System.out.println();
	}
}
public class Class_study {
	public static void main(String[] args) {
		//3가지 객체 생성(this() 미사용)
		A a1 = new A();
		A a2 = new A(10);
		A a3 = new A(10, 20);
		a1.print();
		a2.print();
		a3.print();
		System.out.println();
		
		//3가지 객체 생성(this() 사용)
		B b1 = new B();
		B b2 = new B(10);
		B b3 = new B(10, 20);
		b1.print();
		b2.print();
		b3.print();
	}
}

 

이제 예제를 풀 차례다...

책에 답지가 없당...

채점못한당...

'Study > JAVA' 카테고리의 다른 글

[JAVA] 9장 - 자바 제어자 1  (0) 2022.10.02
[JAVA] 8장 - 클래스 외부 구성 요소  (0) 2022.10.02
[JAVA] 7장 - 클래스 내부 구성 요소(1)  (1) 2022.09.30
[JAVA] 6장 - 클래스와 객체  (0) 2022.09.30
[JAVA] 2장 - 자료형(1)  (0) 2022.05.14