[Java] super, super() (객체지향 2-3)
참조변수 super
super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는 데 사용되는 참조 변수이다.
this를 사용하는 목적 중 하나인 지역변수와 인스턴스 변수를 구별할 때 사용한 것처럼
super는 상속받은 멤버와 자신의 맴버와 이름이 같을 때는 super를 붙여서 구별할 수 있다.
this와 super는 매우 유사하다고 결론 지을 수 있다.
!결론!
this - iv와 lv 비교
super- 상속받은 멤버와 자신의 맴버 비교
import static java.lang.System.out;
public class Main {
public static void main(String[] args) {
Child c = new Child();
c.method();
}
}
class Parent {
int x = 10; /*super.x*/
}
class Child extends Parent {
int x = 20; /*this.x*/
void method() {
out.println("x= "+x);
out.println("this.x= "+this.x);
out.println("super.x= "+super.x);
}
}
x= 20
this.x= 20
super.x= 10
Child 클래스의 int x는 iv인 것을 확인할 수 있다. 하지만 Parent클래스로부터 상속받은 멤버 중 iv x라는 이름을 가진 변수가 있다. 같은 이름을 가지고 있다는 것을 잘 알아두자.
void method 구현부를 보면 처음 x값을 출력한다. 두번째로 this.x 세 번째로 super.x를 출력하는데 super는 상속받은 멤버를 참조하므로 10이 출력된다.
조상의 생성자 super()
this()처럼 super()도 생성자이다. this()는 같은 클래스에서 다른 생성자를 사용할 때 사용되지만, super()는 조상의 생성자를 사용할 때 사용된다.
import static java.lang.System.out;
public class Main{
public static void main(String[] args) {
Child c;
c = new Child(10, 50, 15);
out.printf("x=%d, y=%d, z=%d",c.x,c.y,c.z);
}
}
class Parent {
int x, y;
public Parent(int x, int y) {
this.x = x;
this.y = y;
}
}
class Child extends Parent {
int z;
Child(int x, int y, int z) {
super(x, y);
this.z = z;
}
}
또 하나 생성자의 조건에 대해 알아보자
생성자의 첫 줄에는 반드시 생성자를 적어줘야 한다.
생성자를 적어주지 않으면 컴파일러가 자동적으로 생성자 첫 줄에 super를 첨가한다.
class TestC {
long l;
TestC() {
this(5, 100_000_000); //조건에 성립 this()생성자
}
TestC(int i, long l) {
//super() Object() 굳이 안적어도 컴파일러가 자동으로 첨가해줌.
l=this.l;
}
}
class ErrorT1{
int x,y;
ErrorT1(int x,int y){
this.x=x;
this.y=y;
}
}
class ErrorT2 extends ErrorT1{
int z;
ErrorT2(int x,int y, int z){
this.x=x;
this.y=y;
this.z=z;
}
}
위 코드는 아마 에러가 날 것이다. 위에서 적어 놓은 것처럼 생성자의 규칙 중 생성자의 첫 줄은 반드시 생성자가 와야 한다. ErrorT2 생성자를 보면 첫 줄에 생성자가 없다. 그래서 컴파일러가 자동적으로 super()를 넣는다. 하지만 조상 ErrorT1은 기본 생성자 조차도 없는 상황이라 ErrorT1()이라는 생성자를 찾지 못해 컴파일 에러가 발생한다.
위 코드를 해결하기 위해서는
ErrorT2(int x,int y, int z){
super(5,10);
this.z=z;
}
이런 식으로 super(5,10)를 사용해 ErrorT1(int x, int y) 생성자를 이용한다.
혹은,
class ErrorT1{
int x,y;
ErrorT1(int x,int y){
this.x=x;
this.y=y;
}
ErrorT1(){
/*기본생성자*/
}
}
class ErrorT2 extends ErrorT1{
int z;
ErrorT2(int x,int y, int z){
this.x=x;
this.y=y;
this.z=z;
}
}
ErrorT1(){} 기본 생성자를 만들어서 에러를 없애도록 한다.
🎈이전 글 보기 (객체지향 2-2)