티스토리 뷰

택시 미터기 요금 바꾸기

Meter

package Prac11;

public interface Meter11 {
   // public int BASE_FARE = 3000;     // 기본요금(인터페이스에 정의한 변수는 상수라서 변경할 수 없다.)
    // 이걸 한 번 바꿔보고 싶어요! // 어떻게? 여기서는 지워주시고, 택시 클래스에서 멤버 변수로 선언해주시면 됩니다.


    public abstract void start();
    public abstract int stop(int distance);
}

 

Taxi

package Prac11;

public class Taxi11 implements Meter11 {
    //Meter10 인터페이스의 start와 stop 메서드를 구현해야 한다.

    public int BASE_FARE = 3000;

    @Override
    public void start() {
        System.out.println("운행을 시작합니다.");

    }

    @Override
    public int stop(int distance) {
        int fare = BASE_FARE + distance * 2; //요금 책정하는 방식. 즉 운행이 종료되면 요금을 알 수 있도록 로직을 작성한다.
        System.out.println("운행을 종료합니다. 요금은 " + fare + "원 입니다.");
        return fare;
    }
}

 

실행 클래스

package Prac11;

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

        Taxi11 taxi = new Taxi11();
        taxi.start();
        taxi.stop(20);

        System.out.println("=====================");
        System.out.println("기본요금 인상 후");
        taxi.BASE_FARE = 4500;
        taxi.start();
        taxi.stop(20);
    }
}
/*
정리하자면, 인터페이스 내의 숫자는 상수가 된다.
다른 클래스에 final 키워드가 있기 때문에 인터페이스 내에서 변경이 불가능하다.
따라서 상수로 선언된 요금을 변경하고 싶다면, 요금에 관련된 내용을 Taxi클래스로 옮겨 오시구요.
그러고 나서 구현하는 부분에서 요금을 변경해서 사용하면 된다.
 */

 

순서가 섞여있어서, 전체 코드(앞 포스팅) 보고, 흐름 다시 파악할 것

 

AbstractTestCam

package Prac11;

import Prac11.Camera.FactoryCam11;
import Prac11.Camera.SpeedCam11;

public class AbstractTestCam {
    public static void main(String[] args) {
    //    Camera11 cam = new Camera11(); //처음에 빨간 줄이 뜨는 이유는 이게 추상클래스이기 때문에 객체 생성이 불가능하다.

        FactoryCam11 factoryCam = new FactoryCam11(); // Camera11 fcatoryCam = new Factorycam11(); 도 가능하다는 이야기
        factoryCam.showMainFeature();

        SpeedCam11 speedCam = new SpeedCam11();
        speedCam.showMainFeature();
    }
}
/*
<정리>
추상클래스를 상속받은 자손클래스는
부모타입으로 객체 생성도 가능하다. Camera11 fcatoryCam = new Factorycam11(); 도 가능하다는 이야기
 */

 

InterTest(실행 클래스)

package Prac11;

import Prac11.Camera.FactoryCam11;
import Prac11.Detector.AdvancedFireDetector;
import Prac11.Detector.Detectable;
import Prac11.Detector.FireDetector;
import Prac11.Reporter.AdvancedReporter;
import Prac11.Reporter.NomalReporter;

public class InterTest11 {
    public static void main(String[] args) {
        NomalReporter nomalReporter = new NomalReporter();
        nomalReporter.report();

        AdvancedReporter advancedReporter = new AdvancedReporter();
        advancedReporter.report();

        System.out.println();
        System.out.println("---------------구분선---------------");

        Detectable fireDetector = new FireDetector();
        fireDetector.detect();

        Detectable advancedFireDetector = new AdvancedFireDetector();
        advancedFireDetector.detect();

        System.out.println();
        System.out.println("---------------구분선---------------");

        FactoryCam11 factoryCam = new FactoryCam11();
        factoryCam.setDetector(fireDetector);  // 일반성능으로 화재를 감지합니다.
        factoryCam.setReporter(nomalReporter); // 텍스트로 일반 화재를 신고합니다.
        // factoryCam.setDetector(advancedFireDetector); // 향상된 성능으로 화재를 감지합니다.
        //factoryCam.setReporter(advancedReporter); 두개를 써도 됨 // 직전 30초 영상과 함께 신고를 진행합니다.

        factoryCam.detect();
        factoryCam.report();
    }
}
//다시 FactoryCam 쪽으로 가보면...

 

 

패키지 1.  Camera

Camera

package Prac11.Camera;

// 기능 2가지.
// 1) 사진 촬영 기능
// 2) 동영상 녹화 기능
public abstract class Camera11 {

    public void takePicture() {
        System.out.println("사진을 찍습니다.");
    }

    public void recordVideo() {
        System.out.println("동영상을 녹화합니다.");
    }

    public abstract void showMainFeature();


}

 

FactoryCam

package Prac11.Camera;

import Prac11.Detector.Detectable;
import Prac11.Reporter.Reportable;

public class FactoryCam11 extends Camera11 implements Detectable, Reportable { //Camera가 추상클래스이기 때문에 반드시 구현해야 할 것이 있음을 보여준다.
//implement 뒷부분이 추가된 내용임. 안에 오버라이딩도 해줬어 헷갈리지 말 것.

    private Detectable detector;
    private Reportable reporter;
    // 요 선언한 변수의 값은 외부에서 Setter을 통해 값을 넣어주도록 하겠다.


    public void setDetector(Detectable detector) {
        this.detector = detector;
    }

    public void setReporter(Reportable reporter) {
        this.reporter = reporter;
    }
/*
여기에서는 인스턴스 변수로 두개의 인터페이스를 정의하는 식으로 구현하는 걸로 변수를 정의를 했고,
 setter를 통해서 외부에서 보내주는 파라미터로 Detectable 타입이나 Reportable 타입에 적용함으로써
 화재를 감지하거나 신고할 때, 우리가 조금 전에 전달받은 detector나 reporter를 통해 할 수 있다는 것을 깨달았다.

 따라서 이후에 더 좋은 성능을 가진 것들이 나오면, 해당 기능을 갈아끼우는 걸로 갈아끼우기만 하면!
 보다 더 좋은 것으로 감지를 하거나 신고를 하는 것이 가능하게 된다.
 이러한 기능들은 다른 카메라에서 활용할 수 있도록 설정만 하면 다른 카메라에서 이용할 수도 있다.
 */

    @Override
    public void showMainFeature() { // 주요특징
        System.out.println("화재를 감지한다.");
    }

    @Override
    public void detect() {
        detector.detect();

    }

    @Override
    public void report() {
        reporter.report();
    }
    /*
    우리는 이 객체를 만들 때, 전달받는(Setter을 통해) Detector와 Reporter을 통해서 이것들의 detect와 report기능들을 그대로 쓸 수 있게 된다.
     */

    /*
    이것들을 직접 여기서 구현하는 메서드를 쓰지 않구요.
    Detectable과 Reportable을 구현하는 클래스를 이용해서 만들어볼게요. 설명 이후 일단 주석처리함.(선후관계 잘 파악해라!)

    //InterTest11 만들고 추가한 내용
    public void detect() {
        System.out.println("화재를 감지합니다.");
    }

    public void report() {
        System.out.println("화재신고를 진행합니다.");
    }
}

     */
}
/*
FactoryCam에는 화재를 감지하는 기능과 신고하는 기능이 있었는데, 이것들을 직접 여기서 구현하는 메서드를 쓰지 않구요.
Detectable과 Reportable을 구현하는 클래스를 이용해서 만들어볼게요.
 */

 

SpeedCam

package Prac11.Camera;

public class SpeedCam11 extends Camera11 {
    @Override
    public void showMainFeature() {
        System.out.println("속도 측정, 번호 인식");
    }

    public void detect() {
        System.out.println("사고를 감지합니다.");
    }

    //기능추가
    public void report() {
        System.out.println("사고를 신고합니다.");
    }
}
// 부연설명
/*
그런데 이런 기능들이 점점 많아진다면, 기능의 중복이 발생할 수 있게 되겠지.
이러한 경우에 인터페이스로 빼서 꼭 필요한 기능을 구현할 수 있도록 만들어준다.
*/

 

패키지 2. Detector

FireDetector

package Prac11.Detector;

public class FireDetector implements Detectable {
    @Override
    public void detect() {
        System.out.println("일반성능으로 화재를 감지합니다.");
    }
}

 

AdvancedFireDetector

package Prac11.Detector;

public class AdvancedFireDetector implements Detectable {
    @Override
    public void detect() {
        System.out.println("항상된 성능으로 화재를 감지합니다.");
    }
}

 

Detectable

package Prac11.Detector;

public interface Detectable {
    // <추가> 2. 인터페이스 내에서 어떤 변수를 정의한다고 해보면,
    // String name = "감지자";
    // 앞에 추가되어있는 거 잘 생각하자
    public static final String name = "감지자";

   // <추가> 1. 사실 숨겨져 있던 게 있다.
    public abstract void detect();

}

 

패키지 3. Reporter

NomalReporter

package Prac11.Reporter;

public class NomalReporter implements Reportable {
    @Override
    public void report() {
        System.out.println("텍스트로 일반 화재를 신고합니다.");
    }
}

 

AdvanceReporter

package Prac11.Reporter;

public class AdvancedReporter implements Reportable {
    @Override
    public void report() {
        System.out.println("직전 30초 영상과 함께 신고를 제출합니다.");
    }
}

 

Reportable

package Prac11.Reporter;

public interface Reportable { //인터페이스는 기능이 들어간 경우가 많아서 이름으로 able이 들어가게 많이들 쓴다.
    // 책에서 흔히들 인터페이스를 '기본 설계도'라고 칭하지만, 그냥 뼈대만 가지고 있다고 이해하는 게 더 낫다.
    
    void report(); //Body 생략해서 실행하는 부분의 코드 없이 작성했다.

    // 신고 기능이 두 가지 있다고 해보자.
    //1. Text로 신고하는 일반 신고 //2. 영상을 제공하는 비디오 신고.

}

 

728x90
반응형
Comments
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
250x250