공부/Java

Abstraction

songhees 2025. 12. 10. 21:10

추상화

  • 추상화는 객체에서 공통된 속성과 기능을 추출하는 것
  • 자바에서 추상화는 공통된 속성과 기능을 모아서 추상클래스(Abstract Class)나 인터페이스(Interface)를 정의하는 것이다.
  • 공통 속성은 변수나 상수로 표현하고, 기능추상 메소드로 표현한다.
  • 추상화를 통해서 하위 클래스들이 구현해야 할 공통 기능을 정의할 수 있다.

추상메소드

추상메소드를 상속 받았다면 반드시 메소드 재정의를 통해서 구현부가 있는 메소드로 만들어야 한다.

자식 클래스에 구현을 강제하는 메소드

 

note

  • 공통기능을 추상화하는 메소드
  • 구현부가 없는 메소드 ⇒ 설계만 해 놓은 미완성 메소드
  • 추상클래스와 인터페이스, enum에만 정의할 수 있다.
  • 일반 클래스(구현 클래스)는 추상메소드를 보유할 수 없다.

Abstract Class 🥬

추상클래스
public abstract class Sample {
    // 추상 메소드
    abstract void test1();
    
    // 구현 메소드
    void test3() {
		수행문;
    }
 }

public class Car extends Sample {
    void test1(){
        ...구현 로직
    }
}
  • 추상 클래스는 abstract 키워드가 붙은 클래스
  • 추상 메소드 + 구현 메소드를 둘 다 갖는다.
  • 미완성 설계도(밑그림과 어느 정도 구현됨) ⇒ 미완성 메소드를 포함
    • 추상 클래스는 new 키워드를 사용해서 객체 생성할 수 없다.
    • 구현 클래스는 상속을 통해서 구현해야 한다.

구현 클래스와 차이

  1. 구현부가 없는 메소드를 가질 수 있다는 것이 차이점

구현 클래스와 공통점

  1. 다른 클래스 처럼 생성자, 멤버변수, 메소드를 넣을 수 있다.
  2. extends, implements 둘 다 받을 수 있다.

사용목적

  1. 모든 하위 클래스가 동일한 동작하는 기능추상 클래스에서 구현해서 상속 시킴으로써 하위 클래스의 구현부담을 경감시킨다.
    • 추상 클래스를 사용(extends)하면 인터페이스에서 바로 implements한 것 보다 구현 클래스의 구현 부담이 줄어든다.
  2. 구현클래스마다 구체적인 구현 내용이 다른 것은 구현부가 없는 메소드상태로 두면, 각각의 구현클래스마다 자신에게 맞게 구현부가 없는 메소드를 재정의하게 한다.

구현 내용이 동일한 기능은 추상 클래스에서 구현하여 자식 클래스에게 상속하여 사용한다.

구현 내용이 다른 것(abstract)만 구현클래스에서 재정의하면 된다.

 


Interface

P.S. 자바8 이전 문법 기준
  • 상수, 추상메소드만 보유할 수 있다.
    • 추상클래스보다 추상화 정도가 높아서 구현부를 갖춘 메서드나 멤버 변수를 구성원으로 가질 수 없다.
  • new연산자를 사용해서 객체를 생성할 수 없다.
  • 다중 상속을 지원한다.
  • 기본 설계도(밑그림만 있는)

정의

  1. 구현 클래스가 반드시 구현할 기능을 정의하는 표준(기준, 스펙)
    • 구현 클래스가 재정의할 기능에 대한 명세서
    • 구현부가 없는 추상메소드는 구현클래스가 재정의할 기능에 대한 명세
  2. 구현 클래스가 구현할 기능을 지정
    • 구현메소드의 접근제한자, 반환타입, 메소드명, 매개변수의 타입을 어떻게 정의해야 하는지 알려주는 것
  3. 구현 클래스들의 사용법이 똑같아진다.
    • 인터페이스와 구현클래스들의 메소드 선언부가 같다.
    • 구현내용은 다를 수 있다.

사용목적

  1. 사용방법이 똑같은 객체를 만들려고
  2. 객체관의 관계를 느슨하게 만들려고
    • 다른 클래스로 교체할 때, 수정할 코드가 줄어든다.

응집도는 높고 결합성은 낮게 = 웹의 확장성이 좋다. ⭐⭐⭐⭐⭐


default Methods

인터페이스 안에서 구현이 있는 메소드를 선언할 수 있게 해줌
java 8 이상에서 사용 가능한 기능
public interface Vehicle {
    public default void doSomething(int n) {
        System.out.println("doSomething(Vehicle)");
    }
}

이 메소드를 자식 클래스에서 반드시 구현할 필요가 없어짐 또는 override할 수 있음

 

만든이유?

  1. 기존에 존재하던 인터페이스를 이용하여서 구현된 클래스를 만들고 사용하고 있는데
  2. 인터페이스를 보완하는 과정에서 추가적으로 구현해야 할 혹은 필수적으로 존재해야 할 메소드가 생김
  3. 인터페이스에 메서드를 하나만 추가해도 → 그 인터페이스를 구현하던 모든 클래스에서
  4. 새 메서드를 강제로 구현해야된다.
  5. 이런 경우 default 메소드를 추가하게 된다면 기존 구현체들은 자동으로 기본 구현을 상속받으니 호환성을 유지할 수 있다.

 

구현 클래스와 인터페이스 관계

  • 구현 클래스는 다중 구현이 가능하다. = 구현 클래스는 하나 이상의 인터페이스를 구현한 클래스다.
  • 구현클래스는 구현부가 없는 추상메소드를 포함할 수 없다.
    • 클래스는 인터페이스를 implements 해서 인터페이스를 구현한다.
    • 인터페이스는 class를 extends 할 수 없고, 오직 다른 인터페이스만 extends 할 수 있다.
    • 만약 구현부가 없는 메소드를 상속받으면 무조건 재정의 해야 한다.
  • 구현 클래스는 인터페이스에 정의된 구현부가 없는 메소드를 전부 재정의한 클래스다.
    • 구현클래스에는 구현부가 없는 메소드가 하나도 없다.
    • 재정의를 강제
  • 구현클래스는 implements(구현하다, 구체화하다) 키워드를 사용해서 자신이 구현할 기능이 선언되어 있는 인터페이스들을 지정할 수 있다. 
public class 구현클래스 implements 인터페이스1, 인터페이스2, 인터페이스3, ..., 인터페이스N { 
	// 각 인터페이스에 정의된 구현부가 없는 추장메소드를 전부 재정의 한다. 
    // 구현부가 없는 추상메소드가 하나라도 재정의되지 않으면 구현클래스는 컴파일 오류가 발생 
}
  • 인터페이스끼리 상속할 수 있다. interface Car extends Movable, Stop { }
  • 특정 인터페이스를 구현한 구현클래스들은 언제나 동일한 메소드 사용법을 가지고 있다. → 동작은 다르다.(구현부)
  • 부모 인터페이스 타입의 참조 변수로 자식 객체를 참조할 수 있다.
  • 상속과 구현을 동시 가능 ⇒ public class A extends B implements C { ... }
    • 클래스의 상속은 단일 상속
  • 클래스 vs 클래스(일반/추상 상관 없음) → extends
  • 클래스 vs 인터페이스 → implements
  • 인터페이스 vs 인터페이스 → extends

 

클래스와 인터페이스의 상속

  • interface 간의 관계는 다중 상속, class의 간의 관계는 단일 상속 관계
  • 클래스는 단일 상속이 가능하다.
    • 여러개의 부모에서 같은 메소드가 있을 때 다중 상속의 모호성으로 컴파일 에러가 발생한다.
    • 여러 부모가 같은 super을 공유하는 경우 어떤 순서로 초기화할지 모호하므로 컴파일 에러가 발생한다.
  • 인터페이스는 다중 상속이 가능하다.
    • 단, 같은 명의 메소드가 있을 때 리턴 타입이 다를 때(상하위 관계가 아닐 때) 컴파일 에러
    • 같은 명의 필드가 있을 때 사용시 인터페이스의 이름을 붙인다.
    • Default메소드가 중복되는 경우는 반드시 그 메소드를 오버라이드하는 것으로 모호성을 방지한다.
      • 어떤 인터페이스의 메소드인지 직접 명시해야 된다.
    •