[Java]/Program source (java)

★ 114 - Java 상속(Inheritance) & 메소드 오버라이딩(Method Overriding) : 한 번 Overriding 한 메소드는 원래대로 돌아갈 수 없다.

Jelly-fish 2023. 9. 13. 16:13

부모에게 받은 `write()` 함수 자식 클래스에서 Overriding 함으로써,

자식 객체 참조 변수 ob를 업 캐스팅(부모로 승격) 했을 때자식이 Overriding한 메소드가 호출되는 것을 확인하는 프로그램

 

자식 객체 참조변수 ob부모 클래스(SuperTest114)로 업 캐스팅하여

`((SuperTest114)ob).write();` 를 호출했을 때(부모 클래스의 write() 메소드를 호출하려는 의도)

부모가 물려준 write() 메소드를 자식 객체가 Method Overriding 한 write() 메소드(Sub write() 메소드)로 호출하는 것을 확인.

/*===========================
  ■■■ 클래스 고급 ■■■
  - 상속(Inheritance)
=============================*/

// ※ 메소드 오버라이딩(Method Overrinding)의 특징

//    - 메소드 이름, 리턴 타입, 파라미터 수나 타입이 완전히 일치해야 한다.
//    - 반드시 상속 관계가 있어야 한다.
//    - 재정의된 하위 클래스의 메소드 접근제어지시자는
//      상위 클래스의 메소드 접근제어지시자보다 범위가 크거나 같아야 한다.
//      예를 들어, 상위 클래스 메소드의 접근제어지시자가 『protected』인 경우
//      하위 클래스가 이 메소드를 오버라이딩(Overriding)하는 경우
//      접근제어지시자는 『public』 또는 『protected』이어야 한다.
//    - 『static』, 『final』, 『private』 메소드는
//      오버라이딩(Overriding)할 수 없다.
//    - Exception 의 추가가 불가능하다.
//      즉, 상위 메소드가 가지고 있는 기존의 예외 사항에
//      새로운 Exception 을 추가하는 것은 불가능하다는 것이다.


// 부모 클래스(상위 클래스, super class)
class SuperTest114
{
	private int a = 5;
	protected int b = 10;
	public int c = 20;

	public void write()
	{
		System.out.println("Super write() 메소드 : " + a + " : " + b + " : " + c);
	}
}

// 자식 클래스(하위 클래스, sub class)
class SubTest114 extends SuperTest114
{
	/*
	protected int b = 10;
	public int c = 20;

	public void write()
	{
		System.out.println("Super write() 메소드 : " + a + " : " + b + " : " + c);
	}
	*/


	protected int b = 100;

	public void print()
	{
		//System.out.println("Sub print() 메소드 : " + a + " : " + b + " : " + c);
		//--==>> 에러 발생(컴파일 에러)
		//-- 슈퍼클래스에서 선언된 변수 a 에는 접근할 수 없다.
		//    → private 변수이기 때문에...
		
		System.out.println("Sub print() 메소드 : "  + b + " : " + c);
		//--==>> Sub print() 메소드 : 100 : 20
		// 부모로부터 물려받은 b = 10인데, 자식 클래스에서 b = 100으로 사용했다.
		// 자식 클래스에서 부르는 b는... 지역변수 b! = this.b!(내가 구매한 역행자 단행본)
		// 부모 클래스에서 물려준 b는... super.b!             (부모님이 준 역행자 단행본)

		
		System.out.println("Sub print() 메소드 : "  + b);
		System.out.println("Sub print() 메소드 : "  + this.b);	//this.b -> SubTest114.b 
																// (this가 포함된 클래스로 치환!)
		
		System.out.println("Sub print() 메소드 : "  + super.b);	//super.b -> SuperTest114.b											
		//--==>> Sub print() 메소드 : 100						//(super가 포함된 클래스의 부모로 치환!)
		//       Sub print() 메소드 : 100
		//       Sub print() 메소드 : 10
		//-- 변수 b 는 접근 방법에 따라 다른 b 로 접근 및 출력이 이루어 진다.
		//   슈퍼클래스에서 선언된 b, 서브클래스에서 선언된 b
		
		System.out.println("Sub print() 메소드 : " + c);
		System.out.println("Sub print() 메소드 : " + this.c);
		System.out.println("Sub print() 메소드 : " + super.c);
		//--==>> Sub print() 메소드 : 20
		//       Sub print() 메소드 : 20
		//       Sub print() 메소드 : 20
		//-- 변수 c 는 접근하는데 아무런 제약과 제한이 없다.
		//   슈퍼클래스에서 선언된 c



	}//end print()

	@Override
	public void write()
	{
		//System.out.println("Super write() 메소드 : " + a + " : " + b + " : " + c);
		//--==>> 에러 발생(컴파일 에러)
		//-- 슈퍼클래스에서 선언된 변수 a 에는 접근할 수 없다.
		//    → private 변수이기 때문에...

		System.out.println("Sub write() 메소드 : " + b + " : " + c);
	}



}


// main() 메소드를 포함하는 외부의 다른 클래스
public class Test114
{
	public static void main(String[] args)
	{
		// 하위 클래스(SubTest114) 인스턴스 생성
		SubTest114 ob = new SubTest114();


		ob.print();

		ob.write();
		//--==>> Super write() 메소드 : 5 : 10 : 20
		//--==>> Sub write() 메소드 : 100 : 20

		System.out.println("----------------------- 구분선");
		
		System.out.println(ob.b);
		//--==>> 100

		System.out.println(((SuperTest114)ob).b);	// 형변환 하는 것과 비슷하다!! ((int)'A')!!
		//--==>> 10									// 자식 클래스 타입(Test114, SubClass)을 
		// ※ 슈퍼 부름~!!!							// 부모 클래스 타입으로 변경!!(SuperTest114)


		ob.write();
		//--==>> Sub write() 메소드 : 100 : 20

		((SuperTest114)ob).write();					// 메소드의 오버라이딩을 했기 때문에!!!!!!!!
		//--==>> Sub write() 메소드 : 100 : 20		// 절대 원래의 부모 메소드로 돌아갈 수가 없어!!!!!!!!!!!!

		// check~!!!
		// ※ 메소드와 변수를~!!! 꼭~!!! 구분하여 정리할 것~!!!

	}
}


// 실행 결과

/*
Sub print() 메소드 : 100 : 20
Sub print() 메소드 : 100
Sub print() 메소드 : 100
Sub print() 메소드 : 10
Sub print() 메소드 : 20
Sub print() 메소드 : 20
Sub print() 메소드 : 20
Sub write() 메소드 : 100 : 20
----------------------- 구분선
100
10
Sub write() 메소드 : 100 : 20
Sub write() 메소드 : 100 : 20
계속하려면 아무 키나 누르십시오 . . .

 
*/