[JAVA]16일차[JAVA]17일차(인터페이스(Interface))

정효진·2021년 8월 14일
0

Developer Study

목록 보기
21/47
post-thumbnail

Test113~Test117

◼ 인터페이스(Interface)

▪ 인터페이스(Interface)란

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

▪ 인터페이스는 클래스와 달리 다중 상속이 가능하며 인터페이스 자체도 상속된다.

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

▪ 인터페이스는 상수와 추상 메소드만 가질 수 있으며

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

▪ 인터페이스 특징

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

▪ 인터페이스(Interface) 1 코드 설명📝

// 인터페이스
interface Demo
{
	public static final double PI = 3.141592;
	
	// 인터페이스의 멤버 면수는
	// 『static final』을 별도로 명시하지 않아도
	// 자동으로 『static final』인 상태~!!!
	public int a = 10;  //-- 안됌 static final 상수만 가질 수 있음!! 그런데 됌! 엥


	// 인터페이스의 메소드는 선언만 가능(정의 불가)
	// 자동으로 『abstract』인 상태
	//public void print()
	/*
	{
		System.out.println("PI : " + PI);   // 메소드를 선언만 해야지 정의하는건 안댐
	}
	*/

	//public abstract void print();
	public void print();                //-- 어차피 모든 메소드가 추상이기 때문에 abstract생략 가능~!!
}


// class DemoImpl
// class DemoImpl extends Demo  ( X )
// abstract class DemoImpl extends Demo  ( X )
// class DemoImpl implements Demo  ( X )

//추상 클래스 - 인터페이스를 구현하는 추상 클래스
//abstract class DemoImpl implements Domo
//   ↓ (print를 정의하는 순간 abstract뗀다)
//클래스 - 인터페이스를 구현하는 클래스
class DemoImpl implements Demo           

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

	

}


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

		//DemoImpl ob = new DemoImpl();    //추상클래스는 print만 건들이면 생성가능한데 지금은 안댐
		//-- print() 메소드 재정의 후 가능~!!!

		//DemoImpl obTemp = new DemoImpl();   //더이상 추상이아니고 클래스이기 때문에 인스턴스 생성 가능!
		//Demo ob = (Demo)obTemp;             //DemoImpl는 오버라이딩으로 덮어쓰기 다해서 클래스가 된 아이니까! 업캐스딩 가능한~!!
		//Demo ob = obTemp; 

		//new DemoImpl(); 만 해도 인스턴스 생성됨!! 근데 이제 우리가 담아둘게 필요하니까 앞에 DemoImpl obTemp 쓴것!

		// ○ 업 캐스팅
		// 인터페이스 객체는 상위 객체
		Demo ob = new DemoImpl();
		ob.print();
		//--==>> 인터페이스 메소드 재정의...

		//ob.write();
		//--==>> 에러 발생(컴파일 에러)

		// ○ 다운 캐스팅
		((DemoImpl)ob).write();
		//--==>> 클래스에 정의된 메소드...

		System.out.println(Demo.PI);            //-- static 이어서 가능한~!!
		//--==>> 3.141592

		System.out.println(Demo.a);           //-- 눈에 보이지는 않지만 얘도 static

		//Demo.a = 30;						//-- final 이기 때문에....
		//--==>> 에러발생


	}
}

▪ 인터페이스(Interface)2 코드 설명📝

// 인터페이스  -> 이안에는 추상메소드밖에 못오기 때문에 abstract 생략 가넝한~!!
interface ADemo
{
	public void write();
}

// 인터페이스
interface BDemo
{
	public void print();
}

// ※ 인터페이스는 2개 이상을 구현(implements)할 수 있다.
//   -> 다중 상속이 되지 않는 부분을 보완(보충)하는 개념

// 클래스
//class DemoImpl
//class DemoImpl extends ADemo, BDemo      //--다중 상속안됨
//class DemoImpl implements ADemo, BDemo 
//  ↓
//추상클래스 - 두 인터페이스를 구현한 추상 클래스
//abstract class DemoImpl implements ADemo, BDemo
//  ↓
// 클래스 - 두 인터페이스를 구현한 클래스
class DemoImpl implements ADemo, BDemo 
{
	/*
	public abstract void write();

	public abstract void print();
	*/

	// ※ JDK 1.5(5.0)에서는 인터페이스 메소드를
	//	오버라이딩(Override)할 때
	//  『@Override』 어노테이션(annotation)을 사용할 수 없다.
	//	JDK 1.6(6.0) 이후부터 적용 가능한 문법이다.
	//	단, 상속받은 클래스의 메소드를
	//	오버라이딩(Overriding) 할때에는
	//	JDK 1.5(5.0)에서도 『@Override』 어노테이션(annotation)
	//  사용이 가능하다.

	@Override
	public void write()
	{
		System.out.println("ADemo 인터페이스 메소드 write()...");

	}

	@Override
	public void print()
	{
		System.out.println("BDemo 인터페이스 메소드 write()...");
	}
}

// main() 메소드를 포함하고 있는 외부의 다른클래스
public class Test114
{
	public static void main(String[] args)
	{
		//ADemo ob = new ADemo();      //-- 인터페이스 -> 인스턴스 생성 불가
		//BDemo ob = new BDemo();      //-- 인터페이스 -> 인스턴스 생성 불가

		//ADemo, BDemo 인터페이스를 구현(implements)한 클래스(-> DemoImpl)
		//기반의 인스턴스 생성
		DemoImpl ob1 = new DemoImpl();

		ob1.write();
		ob1.print();
		//--==>> ADemo 인터페이스 메소드 write()...
		//       BDemo 인터페이스 메소드 write()...

		ADemo ob2 = new DemoImpl();        //--업 캐스팅
		BDemo ob3 = new DemoImpl();        //--업 캐스팅

		//ob2.print();				//--==>> 에러 발생 ADemo 에는 print없어서 안됨!
		//ob3.write();				//--==>> 에러 발생 BDemo 에는 write없어서 안됨!

		ob3.print();				
		ob2.write();
		//--==>>BDemo 인터페이스 메소드 write()...
		//		ADemo 인터페이스 메소드 write()...

		((BDemo)ob2).print();		
		((ADemo)ob3).write();	
		//--==>>BDemo 인터페이스 메소드 write()...
		//		ADemo 인터페이스 메소드 write()...
		//가넝한~!! 왜냐면 DemoImpl 가  print랑 write를 둘다 구현했으니까~!!!
		//--DemoImpl 클래스가 두 인터페이스를 모두 구현했기 때문에 가능하다.
		// 만약 DemoImpl 클래스가 이들 중 한 인터페이스만 구현한 상황이라면
		// 이 구문은 런타임 에러 발생하는 구문이 된다.

		// 다운 캐스팅
		((DemoImpl)ob3).write();                    //check~!!
		//--==>> ADemo 인터페이스 메소드 write()...


	}
}

▪ 인터페이스(Interface)3 코드 설명📝

// 인터페이스
interface Demo
{
	public void write();
	public void print();
}


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

	//public abstract void print();
}


// 추상 클래스를 상속받는 추상 클래스
//abstract class DemoImplSub extends DemoImpl
//  ↓
// 추상 클래스를 상속받는 클래스
class DemoImplSub extends DemoImpl
{
	@Override
	public void print()
	{
		System.out.println("print() 메소드 재정의");
	}

}


// main() 메소드를 포함하고 있는 외부의 다른클래스
public class Test115
{
	public static void main(String[] args)
	{
		//Demo ob1 = new Demo();
		//-- 인터페이스 -> 인스턴스 생성 불가 

		//DemoImpl ob2 = new DemoImpl();
		//-- 추상 클래스 -> 인스턴스 생성 불가

		DemoImplSub ob3 = new DemoImplSub();

		ob3.write();
		ob3.print();
		//--==>> write() 메소드 재정의...
		//       print() 메소드 재정의
	}
}

◼ 『extends』vs『implements』

클래스 extends 클래스
클래스 extends 추상클래스

인터페이스 extends 인터페이스
인터페이스 extends 인터페이스, 인터페이스

추상클래스 implements 인터페이스
추상클래스 implements 인터페이스, 인터페이스

클래스 implements 인터페이스
클래스 implements 인터페이스, 인터페이스

※ 인터페이스는 클래스와는 달리 다중 상속이 가능하며,
인터페이스 자체도 상속된다.

※ 인터페이스 멤버 변수인 데이터는
접근제어지시자를 명시하지 않아도 기본 상수(primitive constant)인
static final 의 변경자로 설정된다.
클래스에서 인터페이스를 추가하여 사용할 경우
인터페이스를 구현하는 클래스는
인터페이스의 상위 인터페이스가 제공하는 추상 메소드를 포함한
모든 메소드를 구현하지 않을 경우
추상(abstract) 클래스로 선언해야 한다.

  • 형식
    - 인터페이스는 메소드를 선언만 하고 정의는 없다.
    - 인터페이스를 implements 할 경우 반드시 하위 클래스는
    인터페이스의 모든 메소드를 오버라이딩(Overriding)해야 한다.
    - 인터페이스는 자동적으로 다음과 같이 처리된다.
    멤버 변수 : public static final
    메소드 : public abstract
    - 다중 상속은 콤마(『,』)로 구분되며
    여러 개의 인터페이스를 상속할 수 있다.
    - 인터페이스 끼리 상속할 경우는 『implements』가 아니라 『extends』키워드를 사용한다.

  • 인터페이스의 선언
    인터페이스는 클래스 내부 구현을 제외한 참조형만 선언한 것이므로
    메소드를 선언만 하고 정의할 수 없다.
    또한, 클래스에서의 변수는 값이 변할 수 있지만
    인터페이스에서의 변수는 상수처럼 값이 바뀔 수 없기 때문에
    선언 시에 미리 값을 할당해 놓아야 한다.

  • 인터페이스의 구현
    인터페이스는 클래스를 위한 템플릿이기 때문에
    사용 가능한 인터페이스가 되기 위해서는
    자바 프로그램에서 인터페이스를 구현해 주어야 하는데
    이러한 기능을 하는 것이 『implements』 에약어이다.

  • 클래스는 동시에 두 개 이상의 인터페이스를
    implements 할 수 있다~!!!

▪ 『extends』vs『implements』 코드 설명📝

// 인터페이스
interface ADemo
{
	public void write();
}

// 인터페이스
interface BDemo
{
	public void print();
}

// ※ 클래스는 다중 상속을 지원하지 않지만,
//	  인터페이스는 다중 상속을 지원한다.

// 두 인터페이스(ADemo,BDemo)를 상속받은 인터페이스
interface CDemo extends ADemo, BDemo
{
	//public void write();
	//public void print();

	public void test();
}

// 클래스
// class Demoimpl
//	↓
// 추상 클래스 - CDemo 인터페이스를 구현하는 추상 클래스
// 두 인터페이스(ADemo,BDemo)를 상속받은 인터페이스(CDemo)를 구현한 추상 클래스
//abstract class DemoImpl implements CDemo
//	↓
// 두 인터페이스(ADemo,BDemo)를 상속받은 인터페이스(CDemo)를 구현한 후 모든 메소드를 재정의한 클래스
class DemoImpl implements CDemo
{
	@Override
	public void test()
	{
		System.out.println("test()...");
	}
	
	@Override
	public void write()
	{
		System.out.println("write()...");
	}
	
	@Override
	public void print()
	{
		System.out.println("print()...");
	}
}

// main()메소드를 포함하고 있는 외부의 다른 클래스
public class Test116
{
	public static void main(String[] args)
	{
		// 두 인터페이스르 상속받은 인터페이스를 구현하고
		// 모든 메소드를 재정의한 클래스에 대한 인스턴스 생성
		DemoImpl ob = new DemoImpl();

		ob.test();
		ob.write();
		ob.print();
	}
}

/*
test()...
write()...
print()...
계속하려면 아무 키나 누르십시오 . . .
*/
profile
개발새발

0개의 댓글