🔥 Vamos/Java

1007 | 자바의 정석 기초편 :: ch7-10~7-11

unikue 2022. 10. 7. 23:30

참조변수 super

 

super

: 객체 자신을 가리키는 참조변수

: 인스턴스 메서드(생성자)내에서만 존재 (static 메서드에 사용 불가)

: 조상의 멤버를 자신의 멤버와 구별할 때 사용

 

✔this

: 인스턴스 자신을 가리키는 참조변수. 인스턴스 주소가 저장되며 모든 인스턴스 메서드에 지역변수로 숨겨져있음

: 멤버변수와 로컬변수 구별

 

public static void main(String args[]) {
		Child c = new Child();
		c.method();
	}
}

class Parent { int x=10; }	// 조상멤버 super.x

class Child extends Parent { 	// 상속받았으므로 x, x, method() 세개의 멤버를 가진다
	int x=20;	// 자기 멤버 this.x

	void method() {
		System.out.println("x=" + x);	// 가장 가까운 값을 따라가므로 this.x를 따라감
		System.out.println("this.x=" + this.x);
		System.out.println("super.x="+ super.x);
	}

 

public static void main(String args[]) {
		Child2 c = new Child2();
		c.method();
	}
}

class Parent2 { int x=10; }

class Child2 extends Parent2 {
	void method() {
		System.out.println("x=" + x);
		System.out.println("this.x=" + this.x);
		System.out.println("super.x="+ super.x);
	}
public static void main(String args[]) {
		Child2 c = new Child2();
		c.method();
	}
}

class Parent2 { int x=10; }

class Child2 extends Parent2 { // 상속받는 하나의 x와 메소드만 지닌다
	void method() {
		System.out.println("x=" + x); // 자기x가 없으니까 상속값을 따라감
		System.out.println("this.x=" + this.x); //중복되지 않을땐 super.x와 this.x 둘다 가능.
		System.out.println("super.x="+ super.x);
	}

* 이런경우 참조변수 super와 this는 같은 참조변수 주소값을 가짐

 

 

 

조상의 생성자 super() - 참조변수 super와는 관계 없음

 

super()

: 상속시 생성자와 초기화블럭은 상속되지 않으므로 조상의 생성자를 호출할 필요가 있을때 사용된다!

: 조상 멤버는 조상의 생성자를 호출해서 초기화

: 자손클래스에서 인스턴스 생성시, 자손 멤버와 조상 멤버가 합쳐진 인스턴스가 생성된다

: 조상 멤버들도 초기화 되어야하기 때문에 자손 생성자의 첫문장에서 조상 생성자를 호출해야 한다.

: Object class를 제외한 모든 클래스 생성자 첫 줄에는 생성자(같은 클래스의 다른 생성자 또는 조상의 생성자)를 호출해야 한다. 그렇지않으면 컴파일러가 자동적으로 super();를 생성자 첫줄에 삽입함.

 

👉이렇게 할 경우 오류가 발생하는것은 아니지만 자손의 생성자 Point3D가 조상멤버를 초기화 하는 격이 된다.

자신이 선언한 int z 만 초기화를 담당하는게 사실상 옳기 때문에 super()로 조상 생성자를 호출하여 초기화.

 

Point3D(int x, int y, int z){

  super(x,y); // 조상클래스의 생성자 Point(int x, int y)를 호출. 클래스 대신에 super을 써서 호출하는 것.

  this.z = z; // 자신의 멤버를 초기화

 

* 자손 클래스에서 조상 생성자를 호출할때는 super을 쓴다. *

 

 

모든 클래스 생성자 첫 줄에는 생성자(같은 클래스의 다른 생성자 또는 조상의 생성자)를 호출

point() { this (0,0); } - 자기자신의 생성자 호출

point(int x, int y){ this.x = x; this.y=y;} - 생성자가 없음. 그래서 컴파일러가 super(); 자동으로 추가.

 

* 생성자의 첫줄에는 반드시 생성자를 호출해야 한다 * super() this()

 

꼭 숙지하기!

public static void main(String[] args) {
		Point3D p = new Point3D(1, 2, 3);
		System.out.println("x=" + p.x + ",y=" + p.y + ",z=" + p.z);
	}
}

class Point {
	int x, y;
	Point(){} // 디폴트 생성자 입력- 디폴트 생성자는 멤버변수 아래, 메소드 시작 전에 위치

	Point(int x, int y) {
		
		this.x = x;
		this.y = y;
	}
}

class Point3D extends Point {
	int z;

	Point3D(int x, int y, int z) {
		super(); // 조상인 Point() 호출.> 디폴트 생성자를 끌어옴> 생성자 룰 충족.
		this.x = x;
		this.y = y;
		this.z = z;
	}

* 이렇게 하지 않으려면 super(x,y);로 Point(int x,int y)를 그대로 끌고오면 된다는게 강의 캡쳐의 내용.

 

 


객체지향까지는 괜찮았는데 상속 들어오고부터 개념이 또 어려워졌다 ㅠ_ㅠ