추상클래스

  • 구현 코드 없이 메서드의 선언만 있는 추상 메서드를 포함한 클래스
  • 메서드의 선언 : 반환 타입, 메서드 이름, 매개 변수
  • 메서드 정의 : 메서드 구현과 동일한 의미 구현부를 갖는다
  • 정의가 없는 것이 추상메서드
  • abstract 예약어를 사용

  • 추상 클래스는 new할 수 없음 = 인스턴스화 할 수 없다!!
  • 추상클래스가 아니더라도 abstract를 붙여 추상 클래스를 만들 수 있고 그 경우에도 그 클래스는 new될 수 없다
    하위 클래스로 다시 상속해서 구현 후 사용해야함

추상 클래스 구현하기


기울어진 글씨는 모두 추상 메서드/클래스
Computer.java

public abstract class Computer {
    public abstract void display(); //추상 메서드
    public abstract void typing(); //추상 메서드

    public void turnOn(){
        System.out.println("전원을 켭니다");
    }
    public void turnOff(){
        System.out.println("전원을 끕니다");
    }
}

NoteBook.java

public abstract class NoteBook extends Computer{
    @Override
    public void display() { 
        System.out.println("NoteBook display"); //추상 메서드1 구현부
    }
    //상위에서 추상 메서드를 모두 상속하지 않으면 그 클래스는 추상 클래스가 된다
}

MyNoteBook.java

public class MyNoteBook extends NoteBook{
    @Override
    public void typing() {
        System.out.println("MyNoteBook typing"); //추상 메서드2 구현부
    }
}

템플릿 메서드 패턴

  • 추상메서드나 구현된 메서드를 활용해 코드의 흐름을 정의하는 메서드
  • 그 메서드를 final로 정의하여 하위클래스에서 재정의할 수 없게 한다
  • 프레임워크에서 많이 사용되는 설계 패턴
  • 추상 클래스로 선언된 상위 클래스에서 템플릿 메서드를 활용하여 전체적인 흐름을 정의하고 하위 클래스에서 다르게 구현되어야 하는 부분은 추상 메서드로 선언하여 하위클래스에서 구현하도록 함


    Car.java
public abstract class Car {
    public abstract void drive();
    public abstract void stop();
    public abstract void wiper();
    public void startCar(){
        System.out.println("시동을 켭니다");
    }

    public void turnOff(){
        System.out.println("시동을 끕니다");
    }

    public void washCar(){} //구현을 하지 않았지만 추상 메서드가 아니다. 
    							필요한 경우 하위 클래스에서 재정의하여 사용하는 메서드
    final public void run(){
        startCar();
        drive();
        wiper();
        stop();
        turnOff();
        washCar();
    } // 정해진 시나리오
}

AICar.java

public class AICar extends Car {
    @Override
    public void drive() {
        System.out.println("자율 주행을 합니다");
        System.out.println("자동차가 스스로 방향을 바꿉니다");
    }

    @Override
    public void stop() {
        System.out.println("장애물 앞에서 스스로 멈춥니다");
    }

    @Override
    public void wiper() {

    }

    @Override
    public void washCar() {
        System.out.println("자동 세차를 합니다");
    } // 추상메서드는 아니지만 상위 클래스에서 정의된 메서드를 재정의한 메서드다
}

ManualCar

public class ManualCar extends Car{
    @Override
    public void drive() {
        System.out.println("사람이 운전합니다");
        System.out.println("사람이 핸들을 조작합니다");
    }

    @Override
    public void stop() {
        System.out.println("장애물 앞에서 브레이크를 밟아서 정지합니다");
    }

    @Override
    public void wiper() {

    }
}

인터페이스

  • 모든 메서드가 추상 메서드로 선언됨 -public abstract
  • 모든 변수는 상수로 선언됨 - public static final

    Calc - 인터페이스
    Calculator - 인터페이스를 일부만 구현 - 추상클래스
    CompleteCalc - 모두 구현한 클래스

Calc.java

public interface Calc {
    double PI = 3.14;
    int ERROR = -999999999;
    
    int add(int num1, int num2);
    int substract(int num1, int num2);
    int times(int num1, int num2);
    int divide(int num1, int num2);
}

Calculator.java

public abstract class Calculator implements Calc{
    @Override
    public int add(int num1, int num2) {
        return num1 + num2;
    }

    @Override
    public int substract(int num1, int num2) {
        return num1 - num2;
    }
}

CompleteCalc.java

public class CompleteCalc extends Calculator{
    @Override
    public int times(int num1, int num2) {
        return num1 * num2;
    }

    @Override
    public int divide(int num1, int num2) {
        if (num2 == 0)
            return ERROR;
        return num1/num2;
    }
    public void showInfo(){
        System.out.println("모두 구현했습니다");
    }
}

CalculatorTest.java

public class CalculatorTest {
    public static void main(String[] args) {

        int num1 = 10;
        int num2 = 2;

        CompleteCalc ccalc = new CompleteCalc();
//        Calc calc = new CompleteCalc(); // Calc 인터페이스에서 정의된 메서드만 사용 가능
        System.out.println(ccalc.add(num1,num2));
        System.out.println(ccalc.substract(num1,num2));
        System.out.println(ccalc.times(num1,num2));
        System.out.println(ccalc.divide(num1,num2));

        ccalc.showInfo();
    }
}

인터페이스를 사용하는 이유

  • 클래스나 프로그램이 제공하는 기능을 명시적으로 선언
  • 일종의 클라이언트 코드와의 약속이며 클래스나 프로그램이 제공하는 명세
  • 클라이언트 프로그램은 인터페이스에 선언된 메서드 명세만 보고 이를 구현한 클래스를 사용할 수 있음
  • 어떤 객체가 하나의 인터페이스 타입이라는 것은 그 인터페이스가 제공하는 모든 메서드를 구현했다는 의미
  • 인터페이스를 구현한 다양한 객체를 사용함 - 다형성
  • 예) JDBC 인터페이스
profile
안녕하세요. Chat JooPT입니다.

0개의 댓글