생성자에서 상수 초기화
final로 정의된 값은 상수 라고 한다. 원래는 초기화 하자마자 값을 세팅해줘야 하지만 여기서는 특이하게 생성자에서 상수 초기화를 해줄 것이다. 이 의미는 메인에서 객체 생성을 할 때 인자에 값을 주게 되면 그 값이 바로 상수가 된다는 것이다. 이 후로는 바꿀 수 없는 값이라고 생각하면 됨
일단 코드 훑어 보기
class Card2 //extends Object 생략된 것임
{
final int NUMBER; //상수는 풀대문자.
//final은 원래는 초기화 하자마자 값을 세팅해야함
//그런데 유일하게 생성자에서 세팅하는 것도 가능하다.
final String KIND;
static int width = 100;
static int height = 250;
//생성자 오버로딩
Card2(String kind, int num)
{
KIND = kind;
NUMBER = num;
}
Card2()
{
this("HEART", 1);
//매개변수 2개짜리 다시 호출
//매개변수 없는 경우 이걸 출력
}
Card2(String kind)
{
this(kind, 2);
}
Card2(int num)
{
this("HEART", num);
}
//오버라이딩
public String toString()
//원래는 오브젝트 클래스에 있던 toString임
//주소값을 찾아 주는 것이었음
{
return KIND + "--" + NUMBER;
}
//오버라이딩을 없애면 test1026.Card2@15db9742 이게 뜬다 주소값
/*
* public String toString() { }
* 오브젝트 메소드를 오버라이딩 하고 싶다면 선언부를 똑같이 해줘야 한다!!
*/
}
public class Sample1027_3 {
public static void main(String[] args) {
Card2 c = new Card2("HEART", 10);
//c.NUMBER = 11; 상수 라서 안 됨
System.out.println(c.KIND);
System.out.println(c.NUMBER);
System.out.println(c); //참조형
//System.out.println(c.toString());
//println을 분석하면 인수가 참조형이라서 toString을 알아서 호출을 해준다.
}
}
하나하나 뜯어보기
class Card2 //extends Object 생략된 것임
{
final int NUMBER;
final String KIND;
static int width = 100;
static int height = 250;
모든 클래스에는 Object 클래스 라는 최상단의 클래스를 상속 받고 있다. 그래서 extends Object를 해주지 않아도 클래스 안에 자동으로 포함하고 있다.
final int NUMBER;
final String KIND;
final 상수값은 풀대문자를 사용한다. 원래는 초기화를 하자마자 값을 세팅해야 하지만 유일하게 클래스 내부의 생성자에서 세팅하는 것도 가능하다.
static int width = 100;
static int height = 250;
카드의 크기는 다른 카드들도 똑같으니까 static으로 클래스 변수를 지정해준다. 인스턴스 변수는 객체 생성시에만 만들어주는 특징이 있음
//생성자 오버로딩
Card2(String kind, int num)
{
KIND = kind;
NUMBER = num;
}
생성자 오버로딩
하나의 클래스에서 메소드의 이름이 동일한 경우 매개 변수의 개수와 타입이 다르게 재정의가 가능하다.
객체 생성을 할 때 인자값이 2개인 경우 KIND, NUMBER 차례대로 값을 넣어준다. 그럼 객체 생성을 하면서 등록한 값이 상수에 반영이 되는 것임. (대문자는 클래스에서 지정했던 상수값이고, 뒤쪽의 소문자는 파라미터 값으로 받은 것)
Card2()
{
this("HEART", 1);
}
메인에서 객체생성을 할 때 인자값에 아무것도 넣지 않은 경우 이곳으로 오게 되는데 this()로 다른 생성자를 호출한다. 생성자 오버로딩으로 올라가서 대입하는 것을 갖고 오는 거임. 반드시 첫줄에서 실행이 되어야 함. 데이터 값이 같은 곳 KIND, NUMBER에 이 값이 저장이 됨
//오버라이딩
public String toString()
//원래는 오브젝트 클래스에 있던 toString임
//주소값을 찾아 주는 것이었음
{
return KIND + "--" + NUMBER;
}
}
이 메소드는 원래 Object 클래스에 있던 toString이라는 메소드이다. 주소값을 찾아주는 예약어지만 여기서는 오버라이딩을 하려고 한다. 오버라이딩을 할 때는 선언부를 똑같이 해줘야 하는데 모를 땐 메인에서 toString에서 컨트롤 클릭을 하면 선언부를 볼 수 있음
만약 이 오버라이딩을 없애면? 메인 마지막 출력에서 test1026.Card2@15db9742 이렇게 주소값을 출력한다.
public class Sample1027_3 {
public static void main(String[] args) {
Card2 c = new Card2("HEART", 10);
//c.NUMBER = 11; 상수 라서 안 됨
System.out.println(c.KIND);
System.out.println(c.NUMBER);
System.out.println(c); //참조형
}
}
객체 생성 뒤에 KIND, NUMBER를 바꾸고 싶어도 상수 라서 값을 바꿀 수 없다.
System.out.println(c.toString()); 이것을 하지 않고 System.out.println(c); 이렇게 해주는 이유는 c는 참조형 타입이라서 그럼. println을 분석할 경우 인수가 참조형이라서 toString을 알아서 호출하게 돼 있다. 그러니 굳이 뒤에 메소드를 사용하지 않아도 된다.
print에 참조변수가 오는 경우 주소값을 원래는 찍어야 되는데 위에 있는 메소드를 사용하게 된다. 왜냐하면 같은 메소드가 있을 때 자식부터 실행을 하고 부모 메소드를 실행하기 때문에~~!
출력값
HEART 10 HEART--10 |
매개변수가 1개만 있을 때는?
Card2(String kind)
{
this(kind, 2);
}
Card2(int num)
{
this("HEART", num);
}
매개 변수가 1개일 때는 또 매개변수가 1개인 생성자 2개(kind, num)를 만들어주면 된다.
'개발일지 > Java + Spring' 카테고리의 다른 글
211028(3) Java - 추상클래스 (0) | 2021.10.28 |
---|---|
211028(1) Java - 접근제한자와 캡슐화 (4) | 2021.10.28 |
211027 Java - 클래스 상속 후 부모 생성자 호출 (4) (0) | 2021.10.27 |
211027 Java - 상속과 오버라이딩, 상속 받고 생성자 호출 방법(3) (0) | 2021.10.27 |
211027 Java - 초기화 블록 순서, 생성자 없이 인스턴스 블록에서 구현 (2) (0) | 2021.10.27 |