생성자
iv 초기화를 편하게 하기 위해 만든것
- 인스턴스가 생성 될때마다 호출되는 인스턴스 초기화 메소드
- 인스턴스 생성시 수행할 작업(iv 초기화)에 사용
- 생성자는 이름이 클래스 이름과 같아야 한다.(매개변수가 있던 없던 이름이 같으면 생성자이다)
- 리턴값이 없다 (void를 붙이지 않는다) - 항상 반환값이 없기때문에 붙이지 않는다.
- 모든 클래스는 반드시 생성자가 있어야한다.
Card c = new Car(); 여기서 Car()가 생성자를 호출해주는것이다. (기본생성자)
기본 생성자
- 매개변수가 없는 생성자
클래스 이름() {} == 아무것도 적혀있지 않다 - 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
- 만약 생성자가 하나이상 있는데 아무것도 적혀있지 않은 생성자가 없다면 오류가 발생한다.
class Data1 {
int value;
}
class Data2 {
int value;
Data2(int x) {
value = x;
}
}
class Ex1 {
public static void main(String[] args) {
Data1 d1 = new Data1();
Data2 d2 = new Data2(); // 여기서 컴파일러 에러가 발생한다.
}
}
왜 Data2에서만 오류가 생기는걸까?
Data2를 보면 매개변수가 있는 생성자가 만들어져있다 하지만 매개변수가 없는 생성자가 없기때문에 오류가 발생한다.
컴파일러는 단 한개의 생성자라도 만들어져있다면 자동생성하지 않는다 그렇다면 Data2() {} 를 직접 만들어줘야한다.
그럼 반대로 Data1은 아무것도 없는데 왜 오류가 생기지 않는걸까
아무것도 없기때문에 컴파일러가 자동으로 추가해주는것이다.
매개변수가 있는 생성자
class Car {
String color;
String gearType;
int door;
Car() {} // 기본 생성자
Car(String c, String g, int d) { // 매개 변수가 있는 생성자
color = c;
gearType = g;
door = d;
}
}
iv를 초기화 시켜준다
Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;
이렇게 초기화 해줄수 있는것이다.
Car c = new Car("white", "auto", 4)
생성자 this() 와 참조변수 this
생성자 this()
- 생성자에서 다른 생성자 호출할 때 사용
- 다른 생성자 호출시 첫 줄 에서만 사용이 가능하다.
- 같은 클래스에 있는 생성자를 사용할때는 앞에 생성자 이름을 적는것이 아니라 this를 사용한다.
class Car2 {
String color;
String gearType;
int door;
Car2() {
this("white", "auto", 4);
}
Car2(String color) {
this(color, "auto", 4);
}
Car2(String color, String gearType, int door) {
this.color = color;
this.geartype = gearType;
this.door = door;
}
}
현재 위에 2개의 생성자가 3번의 생성자를 사용한다.
3개의 생성자 모두 iv 초기화를 하고있다.
서로 호출하는 일이 있을수 있다. 이유는 코드의 중복을 제거할 수 있기 때문이다.
코드가 중복된다는게 무슨 말일까?
class Car {
String color;
String gearType;
int door;
Car() {
color = "white";
gearType = "auto";
door = 4;
}
Car(String c, String g, int d) {
color = c;
gearType = g;
door = d;
}
}
여기서 첫번째 생성자에서 디폴트 값을 설정하고 있다.
첫번째 Car의 인자엔 아무것도 없기때문에 디폴트값을 설정하는데 밑에 이미 적혀있는 값을 한번더 적게 되는것이다.
그래서 길게 쓰는것 보다 코드 중복을 제거하여
Car() {
this("white", "auto", 4)
}
로 적으면 되는것이다.
참조변수 this
- 객체(인스턴스) 자신을 가리키는 참조 변수
- 인스턴스 메소드(생성자 포함)에서 사용가능
- 지역변수(lv)와 인스턴스 변수(iv)를 구별할때 사용한다.
Car(String color, String gearType, int door) {
this.color = color;
this.gearType = geartype;
this.door = door;
}
여기서 this가 붙어있는 값이 iv 대입하는 값이 lv이다.
this가 안붙는다면 모두 lv로 인지하기 때문에 붙여주어야 한다.
Car(String c, String g, int d) {
color = c;
gearType = g;
door = d;
}
그럼 여기선 왜 this를 붙여주지 않았을까? 바로 이름이 다르기 때문이다.
우리가 동명이인을 생각해보자, 똑같은 철수라면 김철수와 박철수를 구분해주어야 인지가 편하다
위엔 동명이인인 상태이고 이건 이름조차도 다르기 때문에 this.까지 붙여서 구분해줄 필요가 없는것이다.
※ 정리
this.
- 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.
- 모든 인스턴스메소드에 지역변수로 숨겨진채로 존재한다.
this(), this(매개변수)
- 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
참조변수 Super
- 객체 자신을 가리키는 참조변수, 인스턴스 메소드(생성자)내에만 존재 - static에서 사용 불가
- 조상의 멤버를 자신의 멤버와 구별할 때 사용
예제1)
class Ex7 {
public static void main(Stringp[] args) {
Child c = new Child();
c.method();
}
}
class Parent {
int x = 10; // 이곳이 super 값이다
}
class Child extends Parent {
int x = 20; // 이곳이 this 값이다
void method() {
System.out.println("x=" + x ); // 가까운 x = this.x의 값
System.out.println("this.x=" + this.x); // 자손(Child)의 x값
System.out.println("super.x=" + super.x); // 조상(Parent)의 x값
}
}
예제2)
class Ex7 {
public static void main(Stringp[] args) {
Child c = new Child();
c.method();
}
}
class Parent {
int x = 10; // super와 this 모두 가능
}
class Child extends Parent {
void method() {
System.out.println("x=" + x );
System.out.println("this.x=" + this.x);
System.out.println("super.x=" + super.x); // 모든 x가 Parent의 x를 가리키고 있다.
}
}
super() -- 조상의 생성자
- 조상의 생성자를 호출할 때 사용
- 조상의 멤버는 조상의 생성자를 호출해서 초기화, 이또한 super. 과 헷갈리면 안된다.
- 생성자와 초기화 블럭은 상속이 되지 않는다.
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
this.x = x;
this.y = y; // x, y는 조상의 생성자이다. 이는 굉장히 별로인 코딩이다.
this.z = z;
}
}
조상의 생성자는 조상이 생성자를 다루는것이 맞다
Point3D(int x, int y, int z) {
super(x, y); // 조상클래스의 생성자 Point(int x, int y)를 호출하고
this.z = z; // 자신의 멤버를 초기화한다.
}
- 생성자의 첫 줄에는 반드시 생성자를 호출해야 한다. 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super()를 삽입한다.
class Point extends Object{
int x;
int y;
Point() {
this(0,0);
}
Point(int x, int y) {
여기에 Object의 super생성자
super(); 가 자동으로 생기는 것이다
this.x = x;
this.y = y;
}
}
'Java > 객체 지향' 카테고리의 다른 글
추상 클래스와 추상 메소드 (0) | 2023.05.11 |
---|---|
제어자와 캡슐화 (0) | 2023.05.09 |
오버로딩(Overloading) & 오버라이딩(Overriding) (0) | 2023.05.08 |
호출 스택(call stack) (0) | 2023.05.08 |
메소드(ft . return 문) (0) | 2023.05.08 |