포스트

Day28 Java프로그래밍 기초(추상클래스, 인터페이스)

1. 추상클래스

1.1 추상클래스의 필요성

  • 비슷한 기능을 하는 두개의 클래스를 공통의 메서드로 관리하기 위한 클래스이다.
    • 두개의 정렬 메서드를 확인 해보자
    • 2개의 메서드는 기능은 같지만, sorter.run()과 sorter.start()의 메서드명과 매개변수가 다르다.
    • 같은 기능을 하지만 경우에 따라 2개를 각각 호출해야한다.
    1
    2
    3
    4
    5
    6
    7
    
    static void display(BubbleSort sorter, int[] values) {
      sorter.run(values);
    }
    
    static void display(QuickSort sorter, int[] values) {
      sorter.start(values, 0, values.length - 1);
    }
    

1.2 추상클래스의 개념

  • 그렇기 때문에 추상클래스를 통해 공통의 분모를 수행하는 추상클래스를 생성한다.
    • 추상클래스를 직접적으로 사용하지는 않지만, 같은 메소드와 같은 매개변수로 넘겨 줄수 있다.

    public abstract class Sorter { public void sort(int[] values) {}; }

    public class QuickSort extends Sorter {

    1
    2
    3
    4
    5
    
    @Override
    public void sort(int[] values) {
      start(values, 0, values.length - 1);
    }
    //후략//   }
    

    public class BubbleSort extends Sorter {

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    @Override
    public void sort(int[] values) {
      int size = values.length;
      for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
          if (values[j] > values[j + 1]) {
            //System.out.printf("%d <==> %d\n", values[j], values[j + 1]);
            int temp = values[j];
            values[j] = values[j + 1];
            values[j + 1] = temp;
          }
        }
      }
    }   }
    
  • 여기에 다형성 개념을 대입하면 부모클래스의 변수명으로 자식클래스 타입을 할당할 수 있다.
    • 또한 사용자는 Soter sort = new Soter(); 처럼 직접적인 사용을 할 수 없다.

    Sorter sort = new BubbleSort(); display(sort, values); // OK!

    Sorter sort2 = new QuickSort(); display(sor2, values); // OK!

1.3 추상클래스의 한계

  • 추상클래스를 선언하였지만, 자식클래스에서 추상클래스의 메서드를 사용 안할 수도 있다.
    • 하지만 추상클래스의 메소드를 사용 안하는 경우도 있다.

    public class MergeSort extends Sorter {

    1
    2
    3
    
    void merge(int arr[], int l, int m, int r)
    { // 생략//
    }   }
    

1.4 추상메서드의 활용

  • 추상클래스를 사용 안하면, 상속을 받는 의미가 없다.
    • 따라서 추상클래스의 메소드를 강제적을 사용하게 하는 방법이 필요하다.
    • 추상클래스의 메소드를 강제적으로 사용하게 하는 것이 바로 추상메서드 이다.

    public abstract class Sorter {

    1
    2
    3
    4
    5
    
    // 메서드를 추상 메서드로 선언하는 순간
    // => 모든 서브 클래스는 반드시 이 메서드를 구현해야 한다.
    // => 구현하지 않으면 추상 클래스가 될 수 밖에 없다.
    // => 서브 클래스에게 구현을 강제하는 효과가 있다.
    public abstract void sort(int[] values);   }
    

1.5 인터페이스의 등장

  • 이처럼 추상클래스를 가지고 메소드사용을 강제하는데 제약이 있어, 인터페이스를 사용하게 된다.
    • 추상메서드만 있을 경우, 객체 사용규칙을 정의하는 인터페이스로 전환 가능하다.
    • 추상클래스 안에 일반 메서드가 있다면, 인터페이스로 전환이 불가능하다.

    public interface Sorter {

    1
    2
    3
    4
    
    // 인터페이스는 호출 규칙을 정의하는 것이기 때문에
    // 모든 메서드는 기본이 public 이고, abstract 이다.
    // => 다음과 같이 메서드 선언에 public 과 abstract를 생략해도 된다.
    void sort(int[] values);   }
    

2. 캡슐화


1.1 캡슐화의 필요성

  • 클래스의 필드 값에 직접적인 접근을 하면 해당 필드값을 참조하는 결과값도 영향을 받는다
    • 필드에 직접적인 접근 보다 set과 get 메서드들을 통해 접근하면,
    • 변경에 따른 추가적인 필드 변경 메서드를 추가할 수 있다.

1.2 접근제어자

1
2
3
4
5
6
- private : 클래스에 소속된 같은 멤버만 접근 가능
- (default) : 같은 패키지에 소속된 멤버만 접근 가능
- protected : 같은 패키지에 소속되거나 자손 클래스의 멤버만 접근 가능
- public : 모두 접근 가능

*자식 클래스에서 상속 받아 만든 변수가 아니면 부모클래스로 생성해도 protected 접근불가

1.3 싱글톤 패턴

  • 클래스의 생성자의 접근을 제한하며 static 메서드를 통해 하나의 인스턴스만 생성

    public class Car{ //생성자를 접근제한 private Car();

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
      //하나의 값(전역변수)만을 가지는 인스턴스 선언
      private static Car instance;
        
      //인스턴스의 고유성 여부를 확인
      public static Car getInstance(){
      	if(instance == null){
          	//private은 같은 class내에서 접근 가능
          	instance = new Car();
          }
      //고유한 인스턴스 생성
      return instance;
      }   }
    
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.