추상클래스 & 인터페이스(Abstract Class & Interface Implements)

Joy🌱·2023년 1월 2일
0

☕ Java

목록 보기
27/40
post-thumbnail

👀 추상 클래스

💁‍♀️ 추상클래스(Abstract Class)란,
추상메소드를 0개 이상 포함하는 클래스로써, 사용하기 위해서는 추상클래스를 상속받은 하위 클래스를 이용해서 인스턴스를 생성 (다형성을 활용)

  • 추상클래스로는 인스턴스를 생성할 수 없음

💁‍ 추상메소드(Abstract Method)란,
메소드의 선언부만 있고 구현부가 없는 메소드.
반드시 abstract 키워드를 메소드 헤드에 작성 하여야 함


🙋‍ 잠깐 ! 왜 추상클래스를 사용해야하나요?

  • 추상클래스의 추상메소드오버라이딩에 대한 강제성이 부여 됨
    따라서, 필수 기능을 정의하여 강제성을 부여해 개발 시 일관된 인터페이스를 제공하기 위해 사용

◼ Product Class (Abstract)

[1] 추상 클래스는 abstract 키워드를 작성 ( : 나를 상속받아라)

public abstract class Product {

[2] 추상 클래스는 '필드'를 가질 수 있음

	private int nonStaticField;
	private static int staticField;

[3] 추상 클래스는 '생성자'도 가질 수 있음 (but, 직접적으로 인스턴스 생성은 X)

	public Product() {}
    
    >>> 상속한 클래스에서 Product pro = new Product(); 처럼 인스턴스 생성 불가
    >>> 대신 Product pro = new SmartPhone(); 처럼 다형성을 적용하여 인스턴스 생성은 O

[4] 추상 클래스는 '일반적인 메소드'를 가질 수 있음

	public void nonStaticMethod() {
		System.out.println("Product 클래스의 nonStaticMethod 호출함...");
	}
	
	public void StaticMethod() {
		System.out.println("Product 클래스의 StaticMethod 호출함...");
	}

[5] 추상 클래스에는 abstract를 입력해야함

	public abstract void abstMethod();	>>> 메소드의 바디({})대신 ;로 메소드 작성 마침

📌 Ref.

* 추상 메소드(미완성 메소드)를 가질 수 있음 (추상 클래스만의 장점)
* 추상 메소드를 1개 이상 가질 경우 반드시 추상 클래스여야 함
* 추상 메소드가 0개인 경우 선택적으로 클래스에 abstract 키워드를 작성하여 인스턴스 생성을 막을 수 있음
* 의도적으로 추상메소드가 없더라도 추상클래스를 만들 수 있다 (인스턴스 생성을 막기 위해)

◼ SmartPhone Class

public class SmartPhone extends Product { 

[1] SmartPhone 클래스는 Product 클래스를 상속 받아 구현

이 때, 추상 클래스가 가지는 추상 메소드를 반드시 오버라이딩 해야함 (강제성 부여)

	@Override
	public void abstMethod() {
		System.out.println("Product 클래스의 abstMethod를 오버라이딩 한 메소드 호출함...");
	} 

[2] 추가적인 메소드도 작성 가능

	public void printSmartPhone() {
		System.out.println("SmartPhone 클래스의 printSmartPhone 메소드 호출함...");
	}
}

📌 Ref.

* SmartPhone클래스 내에 Product클래스의 추상메소드인 abstMethod를 오버라이딩 하지않았을 경우,
  The type SmartPhone must implement the inherited abstract method Product.abstMethod() 오류 
  => 상속한 클래스의 추상메소드를 반드시 오버라이딩 해야함(오버라이딩 강제화)

◼ Application Class

public class Application {

	public static void main(String[] args) {

[1] 추상 클래스는 인스턴스 생성 불가

//		Product product = new Product(); 
		>>> Cannot instantiate the type Product 오류

[2] 추상 클래스를 상속 받은 타입을 이용해서 인스턴스 생성

		SmartPhone smartPhone = new SmartPhone();

[3] SmartPhone은 SmartPhone 타입이기도 하지만 Product 타입이기도 함

		System.out.println(smartPhone instanceof SmartPhone); // true
		System.out.println(smartPhone instanceof Product); // true

[4] 다형성을 적용해서 추상 클래스를 레퍼런스 타입으로 활용

		Product product = new SmartPhone();
        >>> 추상 클래스는 미완성이지만 레퍼런스 타입으로 사용하는 것은 아무 문제 없음

[5] 동적 바인딩에 의해 SmartPhone의 메소드가 호출

		product.abstMethod();
        >>> Product 추상 클래스와 연결된 것처럼 보임(정적 바인딩) 
        >>> but, SmartPhone 클래스의 abstMethod를 호출(동적 바인딩)

[6] 추상 클래스가 가진 메소드도 호출 할 수 있음

		product.nonStaticMethod();
		product.StaticMethod();
	}
}

👀 인터페이스

💁‍♀️ 인터페이스(Interface Implements)란,
추상메소드상수 필드만 가질 수 있는 클래스의 변형체


🙋‍ 잠깐 ! 왜 인터페이스를 사용해야하나요?

  • 추상클래스와 비슷하게 필요한 기능을 공통화 해서 강제성을 부여할 목적 (표준화)
  • 자바의 단일상속의 단점을 극복 (다중 상속)

◼ InterProduct Interface

[1] 인터페이스가 인터페이스들을 다중 상속받을 수 있음

public interface InterProduct /*extends java.io.Serializable, java.util.Comparator*/ { 

📌 Ref.

* 인터페이스가 인터페이스를 상속 받을 시에는 extends 키워드를 사용하며, 
  여러 인터페이스를 다중 상속 받을 수 있음

[2] 인터페이스는 상수 필드만 작성 가능 (일반 필드, 일반 메소드 X)

	public static final int MAX_NUM = 100;	>>> 상수 필드는 초기화를 동시에

📌 Ref.

* public static final 제어자 조합을 '상수 필드'라고 부름
  반드시 선언과 동시에 초기화 해주어야 함

[3] 인터페이스에는 상수 필드만을 가질 수 있기 때문에 모든 필드는 묵시적으로 public static final

	int MIN_NUM = 10;

[4] 인터페이스는 생성자를 가질 수 없음

//	public InterProduct() {} 
	>>> Interfaces cannot have constructors 오류

[5] 인터페이스 구현부(body)가 있는 non-static 메소드를 가질 수 없음

//	public void nonStaticMethod() {}
	>>> Abstract methods do not specify a body 오류

[6] 추상 메소드만 작성 가능

	public abstract void nonStaticMethod();

[7] 인터페이스 안에 작성한 메소드는 묵시적으로 public abstract의 의미를 가짐

	void abstMethod();

📌 Ref.

* 인터페이스 안에 작성한 메소드는 묵시적으로 public abstract의 의미를 가짐
  (추상 메소드만 작성 가능하므로)
  따라서 인터페이스의 메소드를 오버라이딩하는 경우, 접근 제한자를 public으로 해야 오버라이딩 가능

[8] static 메소드는 작성 가능

	public static void staticMethod() {
		System.out.println("InterProduct 클래스의 staticMethod 호출됨...");
	}

[9] default 키워드를 사용하면 non-static 메소드도 작성 가능 (오버라이딩 강제화 X)

	public default void defaultMethod() {	>>> default : 인터페이스 안에서만 가능
		System.out.println("InterProduct 클래스의 defaultMethod 호출됨...");
	}
}

◼ Product Class

[1] 클래스에서 인터페이스를 상속받을 때에는 implements 키워드를 사용

//	public class Product extends InterProduct { 
	>>> The type InterProduct cannot be the superclass of Product; a superclass must be a class 오류
    
public class Product extends java.lang.Object implements InterProduct, java.io.Serializable {

>>> 또한, 인터페이스는 다중 상속 받을 수 있고 extends로 다른 클래스를 상속 받는 경우에도,
>>> 그것과 별개로 인터페이스 추가 상속이 가능

[2] InterProduct를 상속받으면 오버라이딩 해야하는 메소드의 강제성이 부여되기 때문에 인터페이스에 작성한 추상 메소드를 전부 오버라이딩 해야함

	@Override
	public void nonStaticMethod() {
		System.out.println("InterProduct의 nonStaticMethod 오버라이딩한 메소드 호출됨...");
	}

	@Override
	public void abstMethod() {
		System.out.println("InterProduct의 abstMethod 오버라이딩한 메소드 호출됨...");
	} 

[3] static 메소드는 오버라이딩 할 수 없음

//	@Override 
	public static void staticMethod() {}
    >>> The method staticMethod() of type Product must override or implement a supertype method 오류

[4] defalt 키워드는 interface 내에서만 작성 가능

//	public default void defaultMethod() {}
	>>> Default methods are allowed only in interfaces 오류
    
	@Override
	public void defaultMethod() {	>>> default 키워드를 제거하면 오버라이딩 가능
		System.out.println("Product 클래스의 defaultMethod 호출됨...");
	}
}

◼ Application Class

public class Application {

	public static void main(String[] args) {

[1] 인스턴스를 생성하지 못 하고 생성자 자체가 존재하지않음

//		InterProduct interProduct = new InterProduct();
		>>> Cannot instantiate the type InterProduct 오류

[2] 다형성을 적용해서 인터페이스를 레퍼런스 타입으로는 활용 가능

		InterProduct interProduct = new Product();

[3] 인터페이스의 추상 메소드를 오버라이딩한 메소드로 동적 바인딩에 의해 호출

		interProduct.nonStaticMethod(); 
		interProduct.abstMethod();
        >>> 정적으로는 InterProduct와 연결된 것처럼 보이나, 
        >>> 동적으로는 오버라이딩한 Product의 메소드가 호출됨 

[4] 오버라이딩 하지 않으면 인터페이스의 default 메소드로 호출, 오버라이딩 하면 Product의 메소드로 호출

		interProduct.defaultMethod(); 
        
        >>> Product클래스의 defaultMethod메소드를 주석 처리 후,
        >>> 위 식을 호출하면 InterProduct클래스의 defaultMethod메소드가 호출

[5] static 메소드는 인터페이스명.메소드명(); 으로 호출

		InterProduct.staticMethod();	>>> 레퍼런스변수명.메소드명();이 아님

[6] 상수 필드는 인터페이스명.필드명();으로 접근

		System.out.println(InterProduct.MAX_NUM);
		System.out.println(InterProduct.MIN_NUM);
	}
}

👀 추상 클래스와 인터페이스의 차이점


profile
Tiny little habits make me

0개의 댓글

관련 채용 정보