추상 클래스(abstract class) / 추상 메소드(abstract method) / 인터페이스(interface)

Agnes Park·2022년 3월 6일
0

JAVA

목록 보기
24/34

1. 추상 클래스(abstract class)와 추상 메소드(abstract method)

클래스: 멤버 변수 (+ 생성자) + 메소드 => 데이터 타입

추상 클래스(abstract class):

  • 추상 메소드를 (하나 이상) 가지고 있는 클래스
  • 클래스 선언할 때 abstract 키워드를 반드시 써 줘야 함
  • 추상 클래스는 인스턴스를 생성할 수 없다. (new 불가능)

추상 메소드(abstract method):

  • 원형(prototype)만 선언돼 있고, 메소드 본체가 정의되지 않은 메소드
  • 메소드 본체가 없기 때문에 {}부분이 없다.
  • 메소드 원형 끝에 ;으로 끝냄.
  • 메소드 이름 앞에 abstract 키워드를 반드시 써 줘야 함

추상 클래스를 사용하는 목적은,
추상 클래스를 상속 받는 자식 클래스에 반드시 구현해야 할 메소드가 있을 경우,
그 메소드를 추상메소드로 만들어서 반드시 override하도록 하는데 목적이 있다.

package com.lec.java.oop04;

public class Abstract01Main {

	public static void main(String[] args) {
		System.out.println("추상 클래스(abstract class)");
		
		// 추상클래스의 인스턴스 생성은 불가능!
//		TestAbstract test1 = new TestAbstract();	// 에러
		
		TestClass test2 = new TestClass();
		test2.test = 100;
		System.out.println(test2.testMethod());	// 자식클래스에서 '구현' 되었기 때문에 사용 가능.
		
		// 다형성
		TestAbstract test3 = new TestClass();
		test3.test = 999;
		System.out.println(test3.testMethod());
		
		
		System.out.println("\n 프로그램 종료");
	} // end main()

} // end class


abstract class TestAbstract{
	int test;
	
	public int getTest() {return test;}
	 
	// 추상 메소드
	// 수식어 리턴타입 메소드이름(매개변수들, ...);
	// 추상 메소드에는 abstract라는 키워드를 반드시 써 줘야 함.
	public abstract int testMethod();
	
}

//추상 클래스를 상속받는 클래스는 반드시 추상메소드를 구현(implement)해야 함 (= 부모쪽의 추상메소드를 오버라이딩하는 것)
//추상 메소드의 본체({ ... })를 만들어줘야 함
class TestClass extends TestAbstract {

	@Override
	public int testMethod() { 
		return test;
	}
	
}

2. 인터페이스(interface)

인터페이스(interface):
1. 모든 메소드가 public abstract으로 선언되고,
2. 모든 멤버 변수가 public static final로 선언된
특별한 종류의 추상 클래스

  • 인터페이스는 interface라고 선언
  • 인터페이스를 구현(상속)하는 클래스에서는 implements 키워드를 사용
  • 인터페이스를 구현(상속)할 때는 개수 제한이 없다. (다중상속)
  • 메소드 선언에서 public abstract는 생략 가능
  • 멤버 변수 선언에서 public static final은 생략 가능

[인터페이스 예시 코드1]

public class Interface01Main {

	public static void main(String[] args) {
		System.out.println("인터페이스(interface)");
		
		TestImpl test1 = new TestImpl();
		test1.testAAA();
		test1.testBBB();
		
		TestImpl2 test2 = new TestImpl2();
		test2.testAAA();
		test2.testBBB();
		test2.testCCC();
		
//		System.out.println(test2.MIN);
		System.out.println(TestInterface.MIN);
		System.out.println(TestInterface2.MIN);
		

		System.out.println("\n 프로그램 종료");
	} // end main()

} // end class

interface TestInterface {
	// 모든 멤버변수는 public static final
	public static final int MIN = 0;
	int MAX = 100;	// public static final 생략.
	
	// 모든 메소드는 public abstract 로 선언
	public abstract void testAAA();
	void testBBB();	// public abstract 생략.
}

interface TestInterface2{
	public static final int MIN = 1;
	public abstract void testAAA();
	public abstract void testCCC();
}

// 인터페이스는 인스턴스를 구현할 수 없고,
// 다른 클래스에서 구현(implement)해야 함.
class TestImpl implements TestInterface {

	@Override
	public void testAAA() {
		System.out.println("testAAA");
	}

	@Override
	public void testBBB() {
		System.out.println("testBBB");		
	}
	
}

// 인터페이스는 다중상속이 가능하다.
class TestImpl2 implements TestInterface, TestInterface2 {

	// testAAA() 는 양쪽 인터페이스에 다 있었지만 
	// 한번만 implement 하면 된다.
	@Override
	public void testAAA() {
		System.out.println("testAAA");
	}
	
	@Override
	public void testBBB() {
		System.out.println("testBBB");
	}
	
	@Override
	public void testCCC() {
		System.out.println("testCCC");
	}
	
}

[인터페이스 예시 코드2]

package com.lec.java.oop07;

public class Interface03Main {

	public static void main(String[] args) {
		System.out.println("인터페이스와 다형성");
		
		TestImple t1 = new TestImple();
		t1.testAAA();
		t1.testBBB();
		
		System.out.println();
		InterfaceAAA t2 = new TestImple();
		t2.testAAA();
//		t2.testBBB();
		
		// 인스턴스는 TestImple 타입으로 생성됐지만,
		// 참조변수의 선언이 InterfaceAAA 타입으로 선언됐기 때문에
		// testAAA()만 보이고, testBBB()는 보이지 않는다.
		// 형변환(Casting)을 통해서 InterfaceBBB에 선언된 메소드를 사용 가능
		((TestImple)t2).testBBB();
		
		System.out.println();
		InterfaceBBB t3 = new TestImple();
		t3.testBBB();
//		t3.testAAA();
		((TestImple)t3).testAAA();
		
		System.out.println("\n 프로그램 종료");
	} // end main()

} // end class
package com.lec.java.oop07;

// 인터페이스를 구현(implements)하는 클래스에서
// 인퍼페이스에 선언만 돼있는 메소드들을 구현(정의)해야 함

public class TestImple implements InterfaceAAA, InterfaceBBB{

	@Override
	public void testBBB() {
		System.out.println("InterfaceBBB : test 구현");
		
	}

	@Override
	public void testAAA() {
		System.out.println("InterfaceAAA : test 구현");
		
	}

} // end class TestImple
package com.lec.java.oop07;

// 인터페이스에 선언되는 모든 메소드는 public abstract임
// public abstract는 생략 가능
// 인터페이스에 선언되는 메소드는 본체({ ... })가 없음
// 메소드 선언 끝에는 세미콜론(;)으로 끝냄

public interface InterfaceAAA {
	
	public abstract void testAAA();
	
	
} // end interface InterfaceAAA
package com.lec.java.oop07;

public interface InterfaceBBB {

	public abstract void testBBB();
	
} // end interface InterfaceBBB

0개의 댓글