본문 바로가기

# 02/Java

[윤성우 열혈자바] 15-2. 메소드 오버라이딩

반응형

상위 클래스의 참조변수가 참조할 수 있는 대상의 범위


class SmartPhone extends MobilePhone { . . . . }


스마트폰은 모바일폰이다.



SmartPhone phone = new SmartPhone ( "010-555-7777", "Nougat" );


따라서 스마트폰 참조변수로 스마트폰 참조 가능하고,






이 역은 성립하지 않음에 주의! (다운캐스팅 안됨)

MobilePhone phone = new SmartPhone( "010-555-777", "Nougat" );


모바일폰 참조변수로 스마트폰 참조도 가능하다. (업캐스팅 가능)


단 , 업캐스팅 시 SmartPhone 인스턴스 생성되었지만 메서드는 MobilePhone에 제한된다. SmartPhone에 만 있는 기능은 사용 못함!!







참조변수의 참조 가능성에 대한 정리


class Cake {

public void sweet() { ... }

}


class CheeseCake extends Cake {

public void milky() { ... }

}


class StrawberrCheeseCake extends CheeseCake {

public void sour() { ... }

}


Cake cake1 = new StrawberrCheeseCake();                            // 접근은 Cake 클래스 변수와, 메소드만 가능

CheeseCake cake2 = new StrawberryCheeseCake();                 // 접근은 CheeseCake 클래스 변수와, 메소드만 가능










참조변수 간 대입과 형 변환


class Cake {

public void sweet() { ... }

}


class CheeseCake extends Cake {

public void milky() { ... }

}



CheeseCake ca1 = new CheeseCake();


Cake ca2 = ca1;                    // 가능!




Cake ca3 = new CheeseCake();


CheeseCake ca4 = ca3;            // 불가능!


이 시점에 컴파일러 및 가상머신은 ca3가 참조하는 대상을 Cake 인스턴스로 판단한다!


ca3가 참조하는 인스턴스의 정확한 클래스 정보는 유지하지 않는다.








참조변수의 참조 가능성 : 배열 기반


class Cake {

public void sweet() { ... }

}


class CheeseCake extends Cake {

public void milky() { ... }

}


Cake cake = new CheeseCake();                         가능!


CheeseCake[] cakes = new CheeseCake[10];        가능!


Cake[] cakes = new CheeseCake[10];                 가능!


상속의 관계가 배열 인스턴스의 참조 관계까지 이어진다.








메소드 오버라이딩 1


class Cake {

public void yummy() {

System.out.println( "Yummy Cake" );

}

}



class CheeseCake extends Cake {

public void yummy() {

System.out.println( "Yummy Cheese Cake" );

}

}


오버라이딩 관계

CheeseCake의 yummy 메소드가 Cake의 yummy 메소드를 오버라이딩!





public static void main( String[] args ) {

Cake c1= new CheeseCake();

CheeseCake c2 = new CheeseCake();


c1.yummy();                    // 오버라이드 했기때문에 참조변수 Cake 메소드가 아닌 인스턴스 오버라이딩 된 메서드 호출됨!

c2.yummy();

}








메소드 오버라이딩 2


class Cake {

public void yummy() { ... }

}


class CheeseCake extends Cake {

public void yummy() { ... }                    // Cake의 yummy를 오버라이딩

}


class StrawberryCheeseCake extends CheeseCake {

public void yummy() { ... }                    // 그리고 CheeseCake의 yummy를 오버라이딩

}


public static void main(String[] args) {

Cake c1 = new StrawberryCheeseCake();

CheeseCake c2 = new StrawberryCheeseCake();

StrawberryCheeseCake c3 = new StrawberryCheeseCake();

c1.yummy();                                                                    // StrawberryCheeseCake 메소드 호출

c2.yummy();                                                                    // StrawberryCheeseCake 메소드 호출

}        








오버라이딩 된 메소드 호출하는 방법


class Cake {

public void yummy() { 

System.out.println( "Yummy Cake" );

}

}




class CheeseCake extends Cake {

public void yummy() {

super.yummy();

System.out.println( "Yummy Cheese Cake" );

}


public void tasty() {

super.yummy();

System.out.println( "Yummy Tasty Cake" );

}

}



오버라이딩 된 메소드를 인스턴스 외부에서 호출하는 방법은 없다.


그러나 인스턴스 내부에서는 키워드 super를 이용해 호출 가능









인스턴스 변수와 클래스 변수도 오버라이딩이 되는가?


class Cake {

public int size;

....

}


class CheeseCake extends Cake {

public int size;

....

}



CheeseCake c1 = new CheeseCake();

c1.size = ...            // CheeseCake의 size에 접근




Cake c2 = new CheeseCake();

c2.size = ...             // Cake의 size에 접근



인스턴스 변수는 오버라이딩 되지 않는다. 따라서 참조변수의 형에 따라 접근하는 멤버가 결정된다.



반응형