오늘은 생성자에 대해 공부할 예정이다.
목차
1. 생성자?
2. 사용 이유
3. this()
4. 멤버변수 초기화 4단계
5. Static
6. Inner Class
7. Local Class

사용자 정보를 데이터로 갖는 Person 클래스를 만든다고 생각해 보자.
그럼 당연히 main 함수에는
참조변수를 이용해서 사용해야 한다.

그리고 Person 객체는 클래스가 없으면 만들지 못하는
사용자 정의 객체다.
따라서 위의 사진처럼 클래스를 만들어줘야 한다.
이때 주의할 점이 있다.
멤버변수는 private으로 하는 것이 기본이고
멤버함수는 public으로 하는 것을 권장한다.
멤버변수를 private으로
멤버함수를 public으로 하면
우리는 이제 main 함수에서 멤버변수를 건드릴 수 없다.
그럼 어떻게 해야 할까?

바로 멤버함수를 이용해 멤버변수를
바꿀 수 있게 하면 된다.
멤버변수에 값을 대입해 주는 기능 메소드를 만들어서
main함수에서 매개변수를 사용해 입력하면 된다.
그리고 출력하는 기능 메소드 역시 만들어서
편하게 출력하게 하자.

그럼 위에 사진처럼
코드가 깔끔해지고 간단해진다.
1. 생성자?

그런데 이렇게 매번 멤버값을 대입해주는 것도
번거로운지
변수처럼 객체도 생성하면서
멤버값을 전달하여 초기화하는 방법이 생겼다.
이때 사용하는 메소드가 생성자(Constructor)이다.

생성자는 만드는 규칙이 있는데
바로 메소드의 이름이 클래스의 이름과 같아야 하고
리턴타입을 명시하지 않아야 한다는 것이다.

이걸 메인함수에서 참조변수를 사용해 만들었을 뿐인데
생성자에 적은 코드가 작동이 된다!
2. 사용 이유

그럼 생성자는 왜 사용할까?
다시 한번 말하지만 이를 이용해서
멤버변수의 값을 초기화할 수 있기 때문이다.
위의 사진처럼
객체를 만들 때부터 값을 넣을 수 있게 되는 것이다.

물론 Person 클래스로 가서
생성자 오버로딩을 통해서
생성자를 만드어줘야 한다.
3. this()
그런데
이때 멤버변수가 100개라면
저렇게 오버로딩을 하나하나 다 적고 있는 것이
너무 귀찮고 번거롭지 않을까?
그때 사용하는 것이
this()이다.

이렇게 생긴 클래스가 있고
그 안에 생성자메소드를 만들었다고 해보자.
그리고 int가 10개 넘는다고 가정해 보자.
그럼 하나하나
this.a this.b this.c .... 를 써가면서
모든 경우의 수를 다 써야 한다.. ㅜㅜ
그러나

this()를 사용하면 쉽게 해결할 수 있다.
내가 이미 쓴 생성자를 호출하는 문법이다.
this(0,0)은
위에 있는 Second(int a, int b)를
호출하는 문법이다.
이를 이용하면 정말 편리하게
사용가능하다.
4. 멤버변수 초기화 4단계
멤버변수의 초기화 단계엔 4단계가 있다.
① 기본값 초기화
② 명시적 초기화
③ 초기화 블럭
④ 생성자

클래스를 만들고
처음 int a; 를 선언하면
0에 해당하는 값이 자동으로 들어간다.
이를 기본값 초기화라고 한다.
그리고 int b = 0;처럼
선언하면서 값을 초기화하는 것을
명시적 초기화라고 한다.
또 { } 안에서
그 값을 설정하는 것이
초기화 블럭이라고 하며
마지막으로 생성자는 오늘 배운 것이다.
5. Static
Static 키워드 : 멤버변수, 메소드, 클래스

우리가 이렇게 int a와 static int b를 만들었다고 해보자.

그리고 메인 함수에
t1, t2, t3라는 참조변수를 선언했다고 했을 때,
이를 그림으로 표현하자면 아래 사진과 같다.

즉 int a는 각각 t1, t2, t3에 존재하나
static 변수인 int b는 한 개만 Test 클래스에 존재한다.
멤버변수는 객체마다 변수가 존재하나
정적 멤버변수는 클래스에 1개만 존재하는 것이다.

그렇기 때문에
22,23,24번 줄에 작성한 출력문은
같은 값을 출력하게 된다.
(static 변수는 하나만 존재하고 이를 출력하기 때문에)
따라서 클래스명을 쓰고 .을 쓰고
그 static 변수를 입력해서 사용하는 게 일반적이다.
(31번 줄 Test.b )

이런 특징 때문에
static 멤버변수는 객체생성과 상관없이 존재하는 변수가 된다.
위의 사진처럼 new First();를 여러 번 적었을 때

First 클래스가 이렇게 코딩되어 있다면
어떤 결과가 나타날까?
First 객체 생성 : 이라는 글자와
1, 2, 3, 4 ..... 등이
계속 나타나는 방식으로 나타날 것이다.


멤버 변수뿐만 아니라
메소드에도 static은 사용가능하다.
그런데 정말 특이한 특징이 있다.
바로 static 메소드 안에서는
static 멤버변수만 사용가능 하다는 것이다.
그리고 static 메소드는
다른 static 메소드를 호출할 수도 있다.

그럼 일반 메소드와 static 메소드의 가장 큰 차이는 무엇일까?
바로 객체 생성이 필요 없다는 것이다.
위의 사진에서 일반 메소드인 aaa를 호출하려면
객체를 생성이 선행되야 한다.
그러나 static 메소드인 bbb를 호출할 땐
클래스명을 적고 .을 찍고 호출해 주면 된다.
(static은 클래스에 하나만 존재하는 것이므로... 칠판에 그린 그림을 참조하자.)

또 static 초기화 블럭은 그냥 초기화 블럭과 차이를 가지는데

이렇게만 적어도

이렇게 출력이 된다.
즉 static 초기화블럭은
클래스가 최초 로딩될 때 수행되므로 생성자 실행과 상관없이 수행되는
특징을 가지고 있다.
이와 달리 일반 초기화블럭(instance 초기화블럭)은
실행할 때마다 수행된다.
6. Inner Class
이너클래스는 클래스 안에 만들어진 클래스이다.

위 사진을 보면 Test 클래스 안에
inner class인 Nice 클래스가 있다.

그러나 Nice 클래스는 메인함수에서 인식이 되지 않는다....
또 이너클래스는 아웃터클래스명으로 인식은 되나 직접 객체 생성이 불가능하다.

그럼 이너클래스는 어떻게 사용할 수 있을까?
바로 이너클래스를 객체로 생성하여 리턴해주는 기능 메소드를 만들면 된다.
이때 리턴타입을 이너클래스명으로 해줘야 한다.

그럼 메인함수에서
위의 사진과 같은 방식으로 사용하여
쓸 수 있다.
그럼 왜 이너클래스를 사용할까?
바로 외부에서 아웃터객체 없이 마음대로 생성하지 못하도록
하기 위해서이다.
(후에 앱 만들기 등 할 때 꼭 필요하다고 한다.)
즉, 아웃터객체를 생성하지 않는다면
이너클래스를 객체로 생성할 수 없도록 하여
잘못된 객체사용을 막아주기 위해서이다.
이런 이너클래스에도 static 키워드가 적용이 되는데
아웃터객체 없이 생성가능한 이너클래스를 만들 때 사용한다.

이런 클래스를 만들었다고 생각해 보자.
그럼 메인함수에서

기존에 우리가 공부했던 방법으로
호출이 가능하다.
7. Local Class
지역클래스(내장클래스, 내부클래스)는
메소드영역안에 설계된 클래스로
설계된 지역 안에서만 인식가능한 클래스이다.

이렇게 새로운 클래스를 만들고
그 안에 aaa라는 메소드를 만들었다.
그리고 그 안에 Good이라는 클래스를 만들었다.
이것이 Local Class이다.
이 지역클래스는 설계된 지역인
aaa메소드에선 객체로 사용가능하다.
그러나 새로 bbb라는 메소드를 만든 경우
Good이라는 객체는
사용할 수 없다.
'# 개발 > Java' 카테고리의 다른 글
Java #8 - 다형성(polymorphism), 추상(abstract), 인터페이스 (국비20일차) (0) | 2023.01.30 |
---|---|
Java #7 - 상속, 오버라이드, Final (국비19일차) (0) | 2023.01.27 |
Java #5 - class 위치, 패키지, 접근제한자 (국비17일차) (0) | 2023.01.25 |
Java 연습문제 #4 (국비15일차) (0) | 2023.01.20 |
Java #4 - 배열 객체 Array, for each문 (국비16일차) (0) | 2023.01.20 |