본문 바로가기

java/자바

[java] super, this

1. super가 뭐지?

 

자식 클래스에서 부모 클래스의 메소드를 오버라이딩하면

부모 클래스의 메소드는 숨겨짐, 자식 메소드만 사용됨

그런데 숨겨진 부모 메소드가 쓰고 싶다면?

그럴땐 super 키워드를 붙여서 부모 메소드를 호출한다.

 

super.부모메소드이름( );

super는 부모 객체를 참조하고 있기 때문에 부모 메소드에 직접 접근할 수 있다.

 

public class Airplane{
	public void land(){
    	System.out.println("착륙합니다");
     }
     public void fly(){
    	System.out.println("일반 비행");
     }
     public void takeOff(){
    	System.out.println("이륙합니다");
     }
 }

부모 클래스 Airplane

 

 

 

public class SupersonicAirplane extends Airplane {
	public static final int 노멀 =1;
    public static final int 슈퍼소닉 =2;
    
    public int flyMode = NORMAL;
    
    @Override
     public void fly(){ // 자식이 부모 메소드 오버라이드 함.
     	if(flyMode == 슈퍼소닉){
        	System.out.println("초음속 비행");
        }else{
        	super.fly(); //부모 메소드 호출
        }
    	
     }// public void fly end
 }//public class SupersonicAirplane end

자식 클래스 supersonicAirplane

 

public class SupersonicAirplaneExample {
	public static void main(String[] args){
    	SupersonicAirplane superA = new SupersonicAirplane();// 자식 객체 생성
        superA.takeOff();
        superA.fly(); // 이륙합니다
        
        superA.flyMode = SupersonicAirplane.SUPERSONIC;
        superA.fly(); // 초음속 비행
        
        superA.flyMode = SupersonicAirplane.NORMAL;
        superA.fly();//일반 비행
        
        superA.land();// 착륙합니다
        }
}

 

 

 

super는 자식 클래스가 부모 클래스로부터 상속 받은 멤버를 참조할 때 사용하는 참조 변수이다.

부모가 가진 멤버 변수 값을 가져온다.

클래스 내의 멤버 변수와 지역 변수의 이름이 같은 경우 구분을 위해 this를 사용하듯..

부모 클래스와 자식 클래스의 멤버 이름이 같은 경우 super를 사용합니다

this와 super는 인스턴스 주소값을 저장합니다. 

static 메서드(클래스 메서드)와는 무관하게 사용됩니다.

 

package com;

class JavaApp {
    public static void main(String[] args) {
        Child child = new Child();
        child.childMethod();
    }
}// class JavaApp

class Parent {
    int x = 10;
}// class Parent

class Child extends Parent {
    int x = 20;

    void childMethod() {
        System.out.println("x=" + x);//자식
        System.out.println("this.x=" + this.x);//자식
        System.out.println("super.x=" + super.x);//부모
    }
}//class Child

결과

 

 

2. super() 가  뭐지?

부모 객체가 먼저 생성되고 -> 자식 객체가 생성 된다.
모든 객체는 클래스의 생성자를 호출해야만 생성된다.

 

 

부모 객체를 생성하기 위해 부모 생성자를 어디서 호출한 것일까?

자식생성자 맨 첫줄에서 부모 생성자를 호출한다.

작성하지 않아도. 컴파일러는 super();가 기본으로 생성한다.

 

 

 

super();는 부모의 기본 생성자를 호출한다.

super(매개값,...);

생성자가 여러개라면 매개값 전달에 따른 생성자를 호출한다. 

일치하는 생성자가 없으면 컴파일 오류가 발생한다.

 

 

 

 

 

 

super()는 부모 클래스의 생성자를 호출하는 메서드이다.

상속받은 자식 클래스가 부모 클래스의 멤버를 사용할 경우가 있다. 

그래서 부모 클래스를 우선적으로 초기화 해야 한다.

 

부모 클래스의 생성자는 자식 클래스의 생성자 첫줄에서 호출 한다.

이러한 부모 클래스의 생성자 호출은 상속 관계에 따라 Object 클래스까지 올라가서 마무리 됩니다.

 

Object 클래스를 제외한 모든 클래스 생성자의 첫 줄에는

반드시 자신의 클래스의 또 다른 생성자,

this() 또는 부모 클래스의 생성자, super()를 호출해야 한다.

하지 않으면 컴파일러가 자동으로 super()를 생성자의 첫줄에서 호출한다.

 

package com;

class JavaApp {
    public static void main(String[] args) {
        Point3D point3d = new Point3D();
        System.out.println("point3d.x=" + point3d.x);
        System.out.println("point3d.y=" + point3d.y);
        System.out.println("point3d.z=" + point3d.z);
    }
}// class JavaApp

class Point {
    int x = 10;
    int y = 20;
    Point(int x, int y) {//생성자
        // 다른 생성자를 호출하지 않아. 컴파일러가 super()를 호출한다.
        // Point 는 부모 클래스라서 Object 클래스의 super() 호출한다.
        this.x = x;
        this.y = y;
    }
}//class Point

class Point3D extends Point {
    int z = 30;
    Point3D() {
        this(100, 200, 300);// Point3D 클래스의 또 다른 생성자 호출
    }

    Point3D(int x, int y, int z) {
        super(x, y);// 부모 클래스 생성자 호출
        this.z = z;
    }
}//class Point3D

결과

 

 

 this(100, 200, 300); ??

3. this() 는 뭐지?

현재 클래스에 정의된 생성자를 부를 때 사용한다.

 

다른 생성자 호출 == this()

생성자 오버로딩이 많아질 경우 생성자 간 중복된 코드가 발생할 수 있다.

매개변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자에서 이러한 현상을 많이 볼 수 있다.

생성자에서 다른 생성자를 호출할 때 this( ) 코드를 사용한다.

 

Car(String model){
	this.model = model;//중복
    this.color = "은색";//중복
    this.maxSpeed =250;//중복
 }
 
 Car(String model, String color){
	this.model = model;//중복
    this.color = color;//중복
    this.maxSpeed =250;//중복
 }
 
 Car(String model, String color, int maxSpeed){
	this.model = model;//중복
    this.color = color;//중복
    this.maxSpeed =maxSpeed;//중복
 }

 

public class Car {
 String 회사 = "현대자동차";
 String model;
 String color;
 int maxSpeed;
 
 Car(){ } //생성자
 Car(String model){
	this(model,"은색", 250);//16번 라인 호출
 }
 
 Car(String model, String color){
	this(model,color, 250);//16번 라인 호출
 }
 
 Car(String model, String color, int maxSpeed){
	this.model = model;//중복 사라짐
    this.color = color;//중복 사라짐
    this.maxSpeed =maxSpeed;//중복 사라짐
 }

 

 

 

4. this는 뭐지?

현재 클래스의 인스턴스.

현재 클래스의 멤버 변수를 지정할 때 사용한다.

매개변수와 클래스 내의 멤버 변수를 구분할 수 있다. this가 붙으면 멤버 변수이다.

 

객체 내부에서 인스턴스 멤버에 접근하기 위해 this를 사용한다.

객체 자신을 this라고 한다.

this.model 은 자신이 가지고 있는 model 필드이다.(인스턴스 멤버인 model, gas는 객체 마다 따로 존재 한다.)

주로 생성자와 메소드의 매개 변수 이름이 필드와 동일한 경우

인스턴스 멤버인 필드임을 명시하고자 할 때 사용한다.

Car(String model){
	this.model = model;
}

void setModel(String model){
	this.model = model;
}

 

 

5. 인스턴스 멤버와 this

인스턴스 멤버 : 객체를 생성한 후 사용할 수 있는 필드, 메소드

인스턴스 멤버 : 인스턴스 필드, 인스턴스 메소드

객체에 소속된 멤버

객체 없이 사용할 수 없다.

 

public class Car{
	String model;//필드
    int gas; //필드
    
    void setSpeed(int speed){// 메소드
    	this.speed = speed;
    } 
 }

gas 필드와 setSpeed 메소드는 인스턴스 멤버이다.

 

외부에서 사용하려면?

Car 객체(인스턴스)를 생성 -> 참조변수 myCar, yourCar로 접근해야한다.

 

public class CarExample{
	public static void main(String[] args){
    	Car myCar = new Car("포르쉐");
        Car yourCar = new Car("벤츠");
        
        myCar.run();
        yourCar.run();
   }// main end
}// class CarExample end

 

인스턴스 필드 gas는 객체마다 따로 존재한다.

인스턴스 메소드 setSpeed()는 객체마다 따로 존재하지 않고, 메소드 영역에 저장, 공유한다.

 

 

6. 메소드 호출?

메소드는 클래스 내부, 외부의 호출에 의해 실행된다.

 

클래스 내부 -> 다른 메소드에서 호출 : 단순한 메소드 이름으로 호출

클래스 외부에서 호출 : 클래스로부터 객체를 생성한 뒤, 참조 변수를 이용해서 메소드를 호출한다.

이유? 객체가 존재해야 메소드도 존재한다.

 

메소드를 호출 하는 법. 외부, 내부

객체 내부에서 호출 객체 외부에서 호출
클래스 내부에서 다른 메소드를 호출 외부 클래스에서 메소드를 호출하려면
객체를 생성해야 한다.
메소드는 객체에 소속된 멤버이므로 객체가 존재하지 않으면 메소드도 존재하지 않기 때문이다.
메소드이름(매개값..); 클래스 참조변수이름 = new 클래스(매개값,...); // 객체 생성

// 메서드 사용
참조변수이름.메소드(매개값,...);

'java > 자바' 카테고리의 다른 글

[java] 싱글톤  (0) 2022.01.01
[java] interface  (0) 2021.12.30
[java] 생성자  (0) 2021.12.30
[java] final  (0) 2021.12.29
[java] 상속  (0) 2021.12.29