코드스테이츠 수강 4주차 1일차에는 생성자와 내부클래스에 대해 배웟다.
1. 생성자
생성자는 클래스에서 객체를 찍어내주는 요소이다.
인스턴스(클래스에서 찍어낸 변수, 메서드)를 초기화 하는 메서드 이다.
우리가 코딩을 할 때 변수 앞에 new를 넣어서 새로운 변수를 만들어 내곤 했는데, 사실 이 new을 사용해서 객체를 생성할 때 "호출되는 것이 생성자" 이다. (new가 생성자라는 말이 아니다, new를 작동시킬때 같이 오는게 생성자다!)
new 는 인스턴스 생성을 담당하고,
생성자는 인스턴스 변수들을 초기화 한다.
생성자는 메서드와 비슷한 구조를 가지고 있으나, 두 가지 차이점이 존재한다.
- 생성자의 이름른 반드시 클래스의 이름과 같아야 한다.
- 생성자는 리턴타입이 없다. (리턴타입 자체가 없음)
작성 예시
클래스명(매개변수) { // 생성자 기본 구조
//생성자 내의 내용
}
쉽게 말하면 생성자는 객체를 찍어낼 때 같이 나오는 녀석인데, 이녀석은 인스턴스 변수를 초기화 하는 것이다.
"초기화" 라는 말이 적절 한게, 이 상생자는 객체가 생성될때 처음에 튀어나오는 놈이므로, 마치 "일단 한번 실행되는 메소드"와 비슷하게 움직인다.
객체를 하나 만들게 되면 생성자의 내용이 실행된다 이거다.(변수를 정해진 값으로 세팅하든, println함수로 출력을 내든, 객체가 생성되는 순간 이 동작을 한다. 만약 println("응애!")을 생성자의 내용으로 써놓으면, 객체가 생성될 때 출력으로 응애! 가 나온다. (객체 탄생))
생성자도 메서드 처럼 오버로딩이 가능하기 때문에 객체를 생성할 때 넣어준 변수에 따라 다르게 생성 가능하다.
오버로딩 예시
public class sengsungEX {
public static void main(String[] args) {
Sengsung sengsung1 = new Sengsung();
Sengsung sengsung2 = new Sengsung("chicken");
Sengsung sengsung3 = new Sengsung(5,10);
}
}
class Sengsung {
Sengsung() { // (1) 생성자 오버로딩
System.out.println("1번 생성자");
}
Sengsung(String str) { // (2)
System.out.println("2번 생성자");
}
Sengsung(int a, int b) { // (3)
System.out.println("3번 생성자");
}
}
//출력
1번 생성자
2번 생성자
3번 생성자
위의 코드에서 아무 변수를 넣지 않은 sensung1을 생성 할 때, 오버로딩 된 생성자 중 변수가 들어있지 않은 메서드를 실행하게 되어 생성자 안의 System.out.println("1번 생성자"); 를 실행하게 된다. (1번 생성자 출력)
아래의 sensung2 , sensung3 생성자도 마찬가지로, 생성 할 때 넣은 변수에 따라 오버라이딩 된 생성자를 실행한다.
기본 생성자
기본 생성자는 매개변수 없이 생성되는 생성자를 의미한다.
위의 코드를 예시로 들면, 오버로딩된 1번 생성자와 같다.
작성예시
클래스명(){} //기본 생성자
chicken(){} // 예시) chicken 클래스의 기본 생성자
"기본" 생성자라고 했는데, 객체를 시용하기 위해서는 항상 있어야 하는것 아닌가? 라고 생각할 수 있는데, 클래스 내에 생성자를 선언 안한 상태로 컴파일 하면, 컴파일러가 알아서 잘 만들어 주기 때문에 상관없다.
매개변수가 있는 생성자
매개변수가 있는 생성자는 메서드처럼 매개변수를 통해 호출된다.
이 때, 생성되는 인스턴스 변수는 매개변수로 초기화가 된다.
오버로딩 예시의 sensung2, sensung3 생성자가 배개변수가 있는 생성자이며, 해당 매개변수 (str, a, b)를 이용한 변수가 있다면 객체를 선언할 때 넣은 (chicken, 5, 10)가 초기값으로 주어지게 된다.
작성예시
클래스명(매개변수){} //기본 생성자
chicken(int A, int B){
System.out.println("치킨%d 마리의 가격은 %d이다.", A, B);
} // 예시) chicken 클래스의 기본 생성자
//출력
치킨A 마리의 가격은 B이다.
위의 코드처럼, 매개변수를 넣어 해당 생성자에서의 변수를 초기화 한다. (A, B는 int현이지만 예를들기 위해 그냥 A, B로 썻다.)
2. this(), this
this()
클래스 안의 메서드들끼리 서로 호출할 수 있듯이, 생성자도 서로 호출이 가능하다.
이때 사용하는 메서드가 this()이다.
생성자를 서로 호출한다는게 감이 안올 수도 있다.
코드로 먼저 보고 설명을 듣는게 좋다.
public class sengsungEX {
public static void main(String[] args) {
Sengsung sengsung1 = new Sengsung();
Sengsung sengsung2 = new Sengsung("chicken");
}
}
class Sengsung {
public Sengsung() { // (1) 생성자 오버로딩
System.out.println("1번 생성자");
}
public Sengsung(String str) { // (2)
this();
System.out.println("2번 생성자");
}
}
//출력
1번 생성자 // 진짜 1번 생성자 호출 할때 나온 출력
1번 생성자 // 2번 생성자 호출할때, this()로 1번생성자가 또 호출됨
2번 생성자 // 2번 생성자 출력
위의 코드를 보면, 2개의 생성자를 만들어서 각각 호출될때의 출력을 볼 수 있는 코드이다.
그런대, 1번 생성자 , 2번 생성자 총 2번의 출력 뿐 아니라, 1번생성자가 한번 더 들어있다.
이유는 매개변수가 있는 생성자 부분을 보면 알 수 있는데, 생성사 내용 작성 시 첫줄에 this();가 있는 것을 알 수 있다.
이 this()메소드는 해당 클래스의 기본 생성자(매서드가 없는 생성자)를 호출하게 되어, 2번째 생성자를 호출할 때 1번째 생성자와 2번째 생성자의 출력이 같이 나오는 것이다!
작동 순서
- 1번째 생성자 호출 -> "1번째 생성자" 출력
- 2번째 생성자 호출 -> "1번째 생성사" 출력 + "2번째 생성자" 출력
this
this는 this()와는 달리 "생성자"를 호출하는게 아닌, 클래스 내의 "객체"(변수,매서드..)를 호출하는 것이다.
이것도 코드를 보면서 이해하는것이 좋다.
public class sengsungEX {
public static void main(String[] args) {
Sengsung sengsung1 = new Sengsung("chicken");
System.out.println(sengsung1.getoutput());
}
}
class Sengsung {
private String CH;
public Sengsung(String CH) { // (1) 생성자 오버로딩
this.CH = CH;
System.out.println("1번 생성자");
}
public String getoutput(){
return CH;
}
}
//출력
1번 생성자 // 진짜 1번 생성자 호출 할때 나온 출력
chicken
위의 코드에서 클래스 안의 CH, 그리고 생성자 안의 CH를 보자.
생성자 안의 CH는 this.CH = CH로 클래스의 CH(클래스의 인스턴스변수)에 접근 한 것이다.
앞서 말한 매개변수가 있는 생성자 호출을 참고해서 보면, new Sensung("chicken"); 코드 작동으로 매개변수가 있는 생성자가 실행되어 "1번 생성자" 출력이 나오고,
System.out.println(sengsung1.getoutput()); 코드로, 클래스 내의 getoutput 메서드가 작동하게 된다.
이 때, sengsung1가 생성될 때, CH에 Sengsung 클래스의 매개변수로 chicken을 넣었고, 생성자에서 또 CH를 가져와서 (this를 이용해서 CH를 가져옴 = chicken을 가져옴) getoutput메서드에 넣는다.
요약하면, 생성자 선언 할 때 넣은 매개변수를 this.CH에 넣어준다는 것이다!
그러면 getoutput는 chicken을 내놓게 되고, 그대로 출력된 것이다.
핵심
- this는 인스턴스를 가리키며, 마치 참조변수를 통해 인스턴스의 멤버에 접근하는 것 처럼, this를 통해 인스턴스의 변수에 접근할 수 있다!
3. 내부 클래스
내부클래스는 단순하게, 클래스 안에 클래스를 선언 한것이다.
뭔가 복잡하게 생각 할 수 있는데, 사실 클래스가 메서드, 변수를 담아놓고 객체를 만드는 것인데, 얘도 그런거라고 생각하면 된다.
사실 우리가 자바 프로그래밍을 할 때 맨 위에 알아서 public class (클래스명(파일명)) 이캐캐 나오는대, 사실 우리는 계속 이너클래스를 쓰고 있었는데 그냥 몰랏다 이렇게 생각하면 쉽게 받아들일 수 있다.
작성예시
class Outer { // 외부 클래스
class Inner {
// 인스턴스 내부 클래스
}
static class StaticInner {
// 정적 내부 클래스
}
void run() {
class LocalInner {
// 지역 내부 클래스
}
}
}
위에서 보다싶이, 클래스 안에 클래스를 3개 만들었다. (총 4개)
- 제일 바깥에 있는 클래스 : 외부 클래스
- 안에 있는 클래스 : 인스턴스 내부 클래스 / 외부클래스의 인스턴스 변수를 사용 가능
- static 붙으면서 안에 있는 클래스 : 정적 내부 클래스 / 외부클래스의 정적 변수를 사용 가능
- 매서드 안에 있는 클래스 : 지역 내부 클래스 (매서드가 작동할때만 잠깐 생기는 일회용 클래스)
'백엔드 > 코드스테이츠 수강' 카테고리의 다른 글
코드스테이츠 수강_4주차_3~4일차_JAVA_객체지향 프로그래밍 심화(다형성, 추상화) (1) | 2022.09.07 |
---|---|
코드스테이츠 수강_4주차_2일차_JAVA_객체지향 프로그래밍 심화 (상속, 캡슐화) (0) | 2022.09.06 |
코드스테이츠 수강_3주차_5일차_JAVA기초 (클래스와 객체, 필드와 메서드) (0) | 2022.09.02 |
코드스테이츠 수강_3주차_4일차_JAVA기초 (배열) (0) | 2022.09.01 |
코드스테이츠 수강_3주차_3일차_JAVA기초 (콘솔 입출력, 제어문) (0) | 2022.08.31 |