abstract 키워드- 추상클래스와 추상메서드

  • 추상메서드(Abstract Moethod) : 선언부만 있고 구현부가 없는 메서드.
  • 추상메서드를 하나라도 가지고 있으면 반드시 추상클래스(Absract Classs)로 선언해야함. 추상메서드없이 추상 클래스를 만들수도 있음!

  • 그렇다면 추상메서드는 어떤 경우에 사용하는 것일까?! 아래 코드를 보면 국적에 따라 사용하는 언어가 다르므로, 인사말도 다르다!

    public class Main {
      public static void main(String[] args) {
      	사람[] 사람들 = new 사람[3];
          사람[0] = new 한국사람();
          사람[1] = new 미국사람();
          사람[2] = new 일본사람();
            
          for(int i = 0; i < 사람들.length; i++) {
          	사람들[i].인사해요();
          }
      }
    }
    public class 한국사람 extends 사람 {
      void 인사해요() {
          System.out.println("안녕하세요~");
      }
    }
    public class 미국사람 extends 사람 {
      void 인사해요() {
          System.out.println("Hello~");
      }
    }
    public class 일본사람 extends 사람 {
      void 인사해요() {
          System.out.println("こんにちは~");
      }
    }
    

    사람 타입의 참조 변수를 통해 하위 클래스의 인스턴스가 가진 인사해요() 메서드를 호출하고 있으니 상위 클래스인 인사해요() 메서드는 반드시 존재해야 한다. 그런데 실수로 사람클래스의 인스턴스를 만들고, 사람객체의 인사해요() 메서드를 호출하면 어떻게 될까?! 사람이 인사를 한다니! 바로 이런 상황에서 추상 메서드를 사용한다 -> 메서드 선언은 있으되 몸체가 없는 형태로 메서드를 구현하는 것이다!

public abstrac class 사람 {
	abstract void 인사해요();
}

위와 같이 abstract로 클래스를 만들게 되면, 실수로 객체생성하는것을 방지 할 수 있다. 뿐만 아니라, 사람을 상속받은 또 다른 국적을 가진 사람의 클래스에서 인사해요() 메서드를 오버라이딩하지 않으면 컴파일 시점에 에러가 발생한다. -> 상속계층에서 추상적인 개념을 나타내기 위한 용도로 추상 클래스를 사용한다! (슈퍼클래스에서는 개념적인 특징, 서브클래스에서 구체적인 행위를 표현)


정리

  • 추상 클래스는 인스턴스, 객체를 만들 수 없다 -> new를 사용할 수 없다.
  • 추상 메서드는 하위 클래스에게 메서드의 구현을 강제한다. -> 오버라이딩 강제
  • 추상 메서드를 포함하는 클래스는 반드시 추상클래스여야 한다.

Interface

  • 자바에서 인터페이스란, 일종의 설계도나 가이드이다. (클래스간의 약속!)
  • 구현 객체들에 대해 동일한 동작을 약속한다. 예를 들어 List인터페이스를 implements하는 클래스인 ArrayList, LinkedList는 공통적으로 add(), indexOf(), get() 등의 메서드를 가지고 있다.
  • 인터페이스는 public 추상메서드와 public 정적 상수만을 가질 수 있다. (자바8 이전) (메서드에 public과 abstract, 속성에 public, static, final을 붙이지 않아도 자바에서 알아서 자동으로 붙여줌!) cf) 자바8부터는 인터페이스를 기초로 하는 람다로 인해 디폴트 메서드라고 하는 객체 구상 메서드와 정적 추상메서드를 지원할 수 있게 언어 스펙이 바뀌었다!
  • 인터페이스는 객체가 아니고, 객체 타입으로만 사용하고, 구현은 실행되는 객체의 메소드에서 한다.
  • 사실 인터페이스의 개념자체는 어렵지않지만 실제 개발에 적용시키니는 쉽지않다. 디자인패턴이나 프레임워크를 통해 습득하는것이 좋은방법이 될 수 있다.

Interface 사용예시로 화장품에서 영양크림을 생각해보자. 보통 영양크림의 용도는 피부개선인데, 기본적으로 피부개선에는 보습, 화이트닝(미백), 주름개선을 생각할 수 있고, 각각의 제조사는 영양크림의 기능을 고객에게 알려줄 의무가 있다. 아래그림은 화장품 제조사에 따란 기능을 표로 표현한것이다.

기능\제조사
S사
C사
H사
보습 효과
있음
있음
없음
화이트닝
있음
없음
없음
주름개선
없음
있음
있음

먼저 그림으로 구조를 살펴보면 다음과 같을 것이다. content01

제조사 각각의 화장품들이 각각의 기능을 가지고, 또 그 기능들을 전체적으로 포괄하는 개념이 영양크림이 된다. (보습, 화이트닝, 주름개선은 영앙크림이 가지고 있는 기능들이다.) 이 개념을 코드화 해보면 다음과 같다.

public interface NourshingCream {
}

public interface Moisturizing extends NourshingCream {
	abstract public void moisturize();
}

public interface Whitening extends NourshingCream{
	public abstract void whiten();
}

public interface WrinkleImprovement extends NourshingCream {
	abstract public void improveWrinkle();
}
public class SNourshingCream implements Moisturizing, Whitening {
	public SNourshingCream() {
		System.out.println("S사 영양크림");
		this.moisturize();
		this.whiten();
		System.out.println();
	}
	@Override
	public void moisturize() {
		System.out.println("이 제품은 보습기능이 포함되어 있습니다.");
	}
	@Override
	public void whiten() {
		System.out.println("이 제품은 화이트닝 기능이 포함되어 있습니다.");
	}
}
public class Main {
	public static void main(String[] args) {
		NourshingCream sNourshingCream = new SNourshingCream();
		NourshingCream cNourshingCream = new CNourshingCream();
		NourshingCream hNourshingCream = new HNourshingCream();	
	}
}

NoursingCream(영앙크림) 인터페이스는 아무것도 없는 껍데기만 있는 인터페이스이다. 하지만 각각의 기능인터페이스들이 NoursingCream 인터페이스를 상속받게 함으로써, 기능들의 데이터 타입을 통일시켜주는 효과를 가져온다.


Abstract와 Interface

  • 공통점
    1) 추상 메소드를 가지고 있다 -> 하위클래스에서 구현해야함! (오버라이딩)
    2) 데이터 타입으로 사용하는것이 주목적 -> 객체생성 목적이 아닌, 데이터타입을 정의하는것이 목적

  • 차이점
    1) 상속, 구현 : 추상클래스는 상속을 통한 사용, 인터페이스는 구현을 통한 사용.
    2) 구성요소 차이 : 추상클래스는 일반 클래스와 동일하게 사용, 인터페이스는 상수, 추상메소드만 존재(자바8이전)
    3) 단일상속, 다중구현 : 추상클래스는 다중상속 지원X, 인터페이스는 다중구현가능


참조1
참조2
참조3