Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

Everything has an expiration date

117 - Java 인터페이스(Interface) : 완전히 미완성! 상수와 추상 메소드만 갖는다. 인터페이스 구현 → implements! 본문

[Java]/Program source (java)

117 - Java 인터페이스(Interface) : 완전히 미완성! 상수와 추상 메소드만 갖는다. 인터페이스 구현 → implements!

Jelly-fish 2023. 9. 14. 14:47
/*==============================
  ■■■ 클래스 고급 ■■■
  - 인터페이스(Interface)
================================*/

/*
○ 인터페이스(Interface)란
	
	완전히 미완성된 채로 남겨져
	인터페이스안에 존재하는 그 어떤 메소드도
	몸체(정의부)가 없기 때문에 사실상 실행 부분이 존재하지 않는다.
	클래스를 위한 템플릿으로써의 기능을 수행하는
	추상 클래스의 한 종류이다.


○	인터페이스는 클래스와 달리 다중 상속이 가능하며
	인터페이스 자체도 상속된다.
	기존의 C++ 언어 등에서 지원되는 다중 상속이
	사용 과정에서 많은 문제점을 노출시켰기 때문에
	자바에서는 다중 상속의 개념을 인터페이스라는 개념으로 변형하여
	인터페이스를 통해 다중 상속을 구현하는 방법을 지원한다.


○	인터페이스는 상수와 추상 메소드만 가질 수 있으며
	인터페이스 안의 메소드들은 접근제어 지시자를 명시하지 않아도
	『public』으로 설정되어 클래스에서 구현(implements) 함으로써
	바로 접근이 이루어질 수 있다.

○ 특징
   - 추상 클래스의 일종으로 선언만 있고 정의가 없다.
   - final 변수는 가질 수 있다. (상수의 개념)
   - 인터페이스는 『public static final』 상수만 만들 수 있다.
   - 인터페이스를 구현하기 위해서는 『extends』 대신에
     『implements』를 이용한다.
   - 하나 이상의 인터페이스를 implements 할 수 있다.
   - 인터페이스를 implements 한 클래스는
     인터페이스의 모든 메소드를 Overriding 해야 한다.
   - 인터페이스가 다른 인터페이스를 상속받을 수 있으며
     이 때, 『extends』 키워드를 사용한다.
	 또한, 클래스와 달리 인터페이스는 다중 상속이 가능하다.



*/

// 인터페이스
interface Demo
{
	public static final double PI = 3.141592;

	// 인터페이스의 멤버 변수는
	// 『static final』을 별도로 명시하지 않아도
	// 자동으로 『static final』인 상태~!!!
	public int a = 10;
	

	// 인터페이스의 메소드는 선언만 가능(정의 불가)
	// 자동으로 『abstract』인 상태
	//public abstract void print();
	
	public void print();// 인터페이스 내부는 다 추상메소드이므로... abstract 키워드 표시안해도 다 추상메소드.
	/*
	{
		System.out.println("PI : " + PI);
	}
	*/

}


// 클래스
//class DemoImpl
//class DemoImpl extends Demo		//--(Ⅹ)
//class DemoImpl implements Demo
//		↓
// 추상 클래스 - 인터페이스를 구현하는 추상 클래스
//abstract class DemoImpl implements Demo
//		↓
// 클래스 - 인터페이스를 구현하는 클래스 (→ print() 메소드 재정의)
class DemoImpl implements Demo
{
	@Override
	public void print()
	{
		System.out.println("인터페이스 메소드 재정의...");
	}

	public void write()
	{
		System.out.println("클래스에 정의된 메소드...");
	}
}


// main() 메소드를 포함하는 외부의 다른 클래스
public class Test117
{
	public static void main(String[] args)
	{
		//Demo ob = new Demo();		//-- 생성 불가~!!!
		//-- 인터페이스는 인스턴스를 생성할 수 없음~!!!


		//DemoImpl ob = new DemoImpl();
		//-- 인터페이스를 implements 만 한 상태에서는 불가
		//   print() 메소드(→ 추상 메소드)를 재정의한 후
		//   abstract 상태에서 벗어난 후 가능
		
		// 업 캐스팅 (묵시적 형변환) 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
		//DemoImpl obTemp = new DemoImpl();	// 자식 객체 생성 ( 부모 객체가 포함되어 있음 )
		//Demo ob = (Demo)obTemp;				// 『 부모 참조변수 = 자식 객체 ( 가능 ! ) 』
		//Demo ob = obTemp;					// 참조변수 타입의 묵시적형변환(업 캐스팅)은 기본타입과 반대로
											// 메모리가 큰 타입(=자식, 부모의 확장버전)을
											// 메모리가 작은 타입(=부모) 으로 자동 형변환 시키기 때문에...
		//○ 업 캐스팅	
		// 인터페이스 객체는 상위 객체
		Demo ob = new DemoImpl();			// 부모 참조변수 ob = 자식 객체 → 가능
		ob.print();
		//--==>> 인터페이스 메소드 재정의...
		// 인터페이스가 정의한 추상 메소드를 호출했음에도 불구하고 제대로 작동
		// ▶ 자식 클래스 DemoImpl에서 Overriding 한 메소드 사용됨.

		//ob.write()	//-->> 불가능! (부모는 자식 것을 마음대로 쓸 수 없다. 위상이 부모 위상으로 바뀌었다.)
		//--==>> 에러 발생 (컴파일 에러)
		//  (부모 위상으로 바뀐 상태에서, 부모(interface Demo) 인터페이스 내부에 write() 메소드가 없다!)
		
		// 다운 캐스팅을 통하여, 자식 클래스로 내려간 후에, write 메소드를 사용하면 가능하다.
		// 부모 참조변수에 자식 객체를 업캐스팅 하여 저장해 두고...
		// 다시 부모 참조변수를 자식 클래스로 다운 캐스팅해 주면
		// 자식 클래스에 write()가 있기 때문에 사용이 가능한 것이다.

		//DemoImpl ob2 = (DemoImpl)ob;
		//ob2.write();
		
		// ○ 다운 캐스팅
		((DemoImpl)ob).write();					// 부모 참조변수 ob를 (DemoImpl) 자식 타입으로 명시적 형변환(다운캐스팅)
		//--==>> 클래스에 정의된 메소드...

		// 상수화된 static 변수이므로, 인터페이스 명으로 변수에 접근.
		System.out.println(Demo.PI);	//-- static 이기 때문에...
		//--==>> 3.141592

		System.out.println(Demo.a);		//-- static 이기 때문에...
		//--==>> 10

		//Demo.a = 300;					//-- final 이기 때문에...
		//--==>> 에러 발생(컴파일 에러)


	}
}