열혈 Java 14 - 상속 참조변수, 메소드 오버라이딩

whipbaek·2021년 12월 28일
0

열혈Java

목록 보기
14/18

상속과 참조변수의 관계

  • 스마트폰과 모바일폰이 존재하고, 스마트폰은 모바일폰을 상속한다.

  • 이러한 경우에,
    모바일폰 참조변수로 스마트폰 인스턴스를 참조할 수 있고
    스마트폰 참조변수로 스마트폰 인스턴스를 참조할 수 있다(이는 당연한 얘기)

  • 모바일폰 참조변수는 스마트폰 인스턴스의 주소값을 가르키지만 "모바일폰 참조변수" 이기 때문에 모바일폰 클래스의 수준까지만 참조가 가능하다.

  • 즉, 모바일폰 참조변수로 스마트폰 인스턴스를 참조하였을때는 모바일폰 클래스의 기능만 수행이 가능하다.

  • 가리키는 것은 가능, but 접근 범위가 달라짐.

  • 역으로는 불가능하다. 위의 그림을 참고해봐도 알겠지만 스마트폰의 기능범위가 더 넓기 때문에 스마트폰의 참조변수가 모바일폰의 인스턴스를 가리킬 수는 없다.


//Phone.java

public class Phone {

	public static void main(String[] args) {
		SmartPhone ph1 =  new SmartPhone("010-111-222", "Nougat");
		MobilePhone ph2 = new SmartPhone("016-555-333", "Nougat"); 	
        	//MobilePhone 참조변수로 SmarPhone 인스턴스 참조가능, but 제한된 참조! 
		
		ph1.answer();
		ph1.playApp();
		System.out.println();
		
		ph2.answer();
		//ph2.playApp();  -> Error ! 

	}

}

class MobilePhone {
	protected String number;
	
	public MobilePhone(String num) {
		number = num;
	}
	
	public void answer() { 
		System.out.println("Hi~ from " + number);
	}
}

class SmartPhone extends MobilePhone {
	private String androidVer;
	
	public SmartPhone(String num, String ver) {
		super(num);
		androidVer = ver;
	}
	
	public void playApp() {
		System.out.println("App is running in " + androidVer);
	}
}

  • 위의 코드에서 cake 참조변수 ca3은 CheeseCake인스턴스를 가리키고 있다.
    그리고 ca3은 cake 클래스의 기능만 수행할 수 있을것이다.

  • 그 상태로 CheeseCake 참조변수에 할당할려고 할시 오류가 발생한다.

  • 이는 컴파일러에서 ca3이 참조하는 수준을 보고 판단하기 때문이다.
    컴파일러는 ca3가 참조하는 인스턴스의 정확한 정보를 유지하지는 않는다.
    ca3은 cake를 참조하는 참조변수라고 생각하기 때문에, Cheesecake 참조변수로의 대입에 오류를 발생시킨다.

  • 상속의 개념은 배열까지도 확장 될 수 있다.

메소드 오버라이딩

  • overriding : 자식 메소드가 부모 메소드를 가림
    (반환형, 메소드의 이름, 매개변수 선언이 같을때)


public class Cake {

	public void yummy() {
		System.out.println("Yummy Cake");
	}
	
	
	public static void main(String[] args) {
		Cake c1 = new CheeseCake();
		CheeseCake c2 = new CheeseCake();
		
		c1.yummy();
		c2.yummy();
	}

}

class CheeseCake extends Cake {
	public void yummy() {
		System.out.println("Yummy Cheese Cake");
	}
}

실행결과

  • 자식 클래스에서 부모 클래스의 메소드를 오버라이딩하면, 부모 클래스의 메소드는 가려진다.

  • 위의 코드에서 Cake 참조변수로 CheeseCake를 참조했음에도 불구하고, Cake의 yummy 메소드가 실행되는게 아닌, CheeseCake의 yummy메소드가 실행된다.

  • 오버라이딩 된 메소드는 외부에서 . 연산을 통하여 실행이 불가능하다.

  • 단, Cake c1 = Cake(); c1.yummy(); 의 접근이 불가능하다는 뜻이 아니다! 참조변수가 CheeseCake 인스턴스를 가리킬 경우에만 해당되는것을 명심.

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

  • 자식 클래스에서 super.메소드() 를 사용하면 가능하다.

public class Cake {

	public void yummy() {
		System.out.println("Yummy Cake");
	}
	
	
	public static void main(String[] args) {
		Cake c1 = new CheeseCake();
		CheeseCake c2 = new CheeseCake();
		
		c1.yummy();
		c2.yummy();
	}

}

class CheeseCake extends Cake {
	public void yummy() {
		super.yummy(); //가려진 메소드를 호출함!
		System.out.println("Yummy Cheese Cake");
	}
}

실행결과

인스턴스 변수는 오버라이딩 가능?

  • 인스턴스 변수는 오버라이딩의 대상이 아니다.

출처 : 윤성우의 열혈Java 프로그래밍

profile
코딩 및 CS에 관하여 공부합니다.

0개의 댓글

관련 채용 정보