추상화(Abstraction)

김수민·2023년 3월 11일
0

백엔드 부트캠프

목록 보기
16/52

추상화

  • 추상화: 기존 클래스들의 공통적인 요소들을 뽑아서 상위 클래스를 만들어내는 것

abstract 제어자

  • abstract는 주로 클래스와 메서드를 형용하는 키워드로 사용되는데, 메서드 앞에 붙은 경우를 '추상 메서드(abstract method)', 클래스 앞에 붙은 경우를 '추상 클래스(abstract class)'라 부름
  • 어떤 클래스에 추상 메서드가 포함되어 잇는 경우 해당 클래스는 자동으로 추상 클래스가 됨
  • 추상 메서드는 충분히 구체화되지 않은 '미완성 메서드'이며, 미완성 메서드를 포함하는 클래스는 '미완성 클래스'를 의미하는 추상 클래스가 됨
  • 메서드 바디가 완성되기 전까지 이를 기반으로 객체 생성이 불가함

추상 클래스

  • 추상 클래스를 만드는 이유: 상속 관계에 잇어 새로운 클래스를 작성하는데 매우 유용
    - 메서드의 내용이 상속을 받는 클래스에 따라서 종종 달라지기 때문에 상위 클래스에서는 선언부만을 작성하고, 실제 구체적인 내용은 상속을 받는 하위 클래스에서 구현하도록 비워둔다면 설계하는 상황이 변하더라도 보다 유연하게 대응할 수 있음
  • 추상 클래스를 사용하면 상속을 받는 하위 클래스에서 오버라이딩을 통해 각각 상황에 맞는 메서드를 구현 가능
  • 추상 클래스는 자바 객체지향 프로그래밍의 마지막 기둥인 추상화를 구현하는데 핵심적인 역할을 수행
  • 상속계층도의 강층부에 위치할수록 추상화의 정도가 높고 그 아래로 내려갈수록 구체화 = 상층부에 가까울수록 더 공통적인 속성과 기능들이 정의되어 있음

final

위치의미
클래스변경 또는 확장 불가능한 클래스, 상속 불가
메서드오버라이딩 불가
변수값 변경이 불가능한 상수
final class FinalEx { // 확장/상속 불가능한 클래스
	final int x = 1; // 변경되지 않는 상수

	final int getNum() { // 오버라이딩 불가한 메서드
		final int localVar = x; // 상수
		return x;
	}
}

더이상 변경이 불가하거나 확장되지 않은 성질

인터페이스

  • 인터페이스: 서로 다른 두 시스템, 장치, 소프트웨어 따위를 서로 이어주는 부분 또는 그런 접속 장치
  • 추상 클래스: 설계가 모두 끝나지 않은 미완성 설계도, 인터페이스: 기초적인 밑그림
  • 인터페이스는 기본적으로 추상 메서드와 상수만을 멤버로 가질 수 있다는 점에서 추상 클래스에 비해 추상화 정도가 높음

인터페이스의 기본 구조

  • class 키워드 대신 interface 키워드를 사용함
  • 내부의 모든 필드가 public static final로 정의되고, staticdefault 메더스 이외의 모든 메서드가 public abstract로 정의됨
public interface InterfaceEx {
    public static final int rock =  1; // 인터페이스 인스턴스 변수 정의
    final int scissors = 2; // public static 생략
    static int paper = 3; // public & final 생략

    public abstract String getPlayingNum();
		void call() //public abstract 생략 
}

인터페이스 안에서 상수를 정의하는 경우에는 반드시 public static final로, 메서드를 정의하는 경우에는 public abstract로 정의되어야하지만 일부분 또는 전부 생략 가능. 생략된 부분은 컴파일러가 자동으로 추가해줌.

인터페이스의 구현

class 클래스명 implements 인터페이스명 {
	... // 인터페이스에 정의된 모든 추상메서드 구현
}

특정 인터페이스를 구현한 클래스는 해당 인터페이스에 정의된 모든 추상메서드를 구현해야함.
-> 어떤 클래스가 특정 인터페이스를 구현한다는 것은 그 클래스에게 인터페이스의 추상 메서드를 반드시 구현하도록 강제하는 것
= 그 인터페이스가 가진 모든 추상 메서드를 해당 클래스 내에서 오버라이딩하여 바디를 완성함.

인터페이스의 다중 구현

클래스에서 다중 상속이 불가능했던 이유는 만약 부모 클래스에 동일한 이름의 필드 또는 메서드가 존재하는 경우 충돌이 발생함.
인터페이스는 애초에 미완성된 멤버를 가지고 있기 때문에 충돌이 발생할 여지가 없고 안전하게 다중구현이 가능.

인터페이스의 장점

역할과 구현을 분리시켜 사용자 입장에서는 복잡한 구현의 내용 또는 변경과 상관없이 해당 기능을 사용할 수 있음.
= 기능이 가지는 역할과 구현을 분리시켜 사용자로 복잡한 기능의 구현이나 교체/변경을 신경쓰지 않고도 코드 변경의 번거러움을 최소화하고 손쉽게 해당기능을 사용할 수 있음.
개발자 입장에서는 선언과 구현을 분리시켜 개발시간을 단축할 수 있고, 독립적인 프로그래밍을 통해 한 클래스의 변경이 다른 클래스에 미치는 영향을 최소화할 수 있음.

인터페이스 활용 예제

nterface Customer {
  String getOrder();
}

class CafeCustomerA implements Customer {
  public String getOrder(){
		return "a glass of iced americano";
	}
}

class CafeCustomerB implements Customer {
  public String getOrder(){
		return "a glass of strawberry latte";
	}
}

class CafeOwner {
  public void giveItem(Customer customer) {
    System.out.println("Item : " + customer.getOrder());
  }
}

public class OrderExample {
    public static void main(String[] args) throws Exception {
        CafeOwner cafeowner = new CafeOwner();
        Customer cafeCustomerA = new CafeCustomerA();
        Customer cafeCustomerB = new CafeCustomerB();

        cafeowner.giveItem(cafeCustomerA);
        cafeowner.giveItem(cafeCustomerB);
    }
}

// 출력값
Item : a glass of iced americano
Item : a glass of strawberry latte

0개의 댓글