簡體   English   中英

在Java中的泛型類中為特定類型實現方法

[英]Implement a method for specific type in a generic class in Java

我試圖實現一個通用類Distance來處理Integer和LocalDateTime。(物理距離和時間距離)我想創建一個方法來顯示一個點是否在此距離之內。 如何為Integer和LocalDateTime實現不同的邏輯?

我試圖創建一個擴展距離的類LocalDateTimeDistance,但是這樣做很不對勁,因為Distance已經表明了LocalDateTime距離,而且我認為將所有Distance更改為LocalDateTimeDistance是如此奇怪。

public class Distance<T> {
    private T start
    private T end
}
public class LocalDateTimeDistance<T extends LocalDateTime> extends Distance<T> {
    public boolean isPointWithinDistance(LocalDateTime ldt){
        LocalDateTime from = this.getFrom();
        LocalDateTime to = this.getTo();

        return (fromLocalDate.isBefore(ldt) || fromLocalDate.isEqual(ldt)) &&
               (toLocalDate.isAfter(ldt) || toLocalDate.isEqual(ldt));
    }
}
public class IntegerDistance<T extends Integer> extends Distance<T> {
    public boolean isPointWithinDistance(Integer){
        //Logic for integer distance...
    }
}

你快到了! 您有經典的策略模式

您應該在兩個不同的類中實現計算邏輯,並在點類型中僅選擇所需的一個基數。

public final class Distance<T> {

    private final T start;
    private final T end;

}

public final class DistanceService {

    private final Predicate<LocalDateTime> dateTimeDistance = new Predicate<LocalDateTime>() {
        private final Distance<LocalDateTime> distance = new Distance<>(null, null);

        @Override
        public boolean test(LocalDateTime point) {
            return distance.getStart().isBefore(point) && point.isBefore(distance.getEnd());
        }
    };

    private final Predicate<Integer> integerDistance = new Predicate<Integer>() {
        private final Distance<Integer> distance = new Distance<>(100, 200);

        @Override
        public boolean test(Integer point) {
            return distance.getStart() <= point && point <= distance.getEnd();
        }
    };

    public boolean isPointWithinDistance(LocalDateTime point) {
        return dateTimeDistance.test(point);
    }

    public boolean isPointWithinDistance(int point) {
        return integerDistance.test(point);
    }
}

DistanceService service = new DistanceService();
boolean localDateTimeCheck = service.isPointWithinDistance((LocalDateTime)null);
boolean integerCheck = service.isPointWithinDistance(150);

首先,我不一定建議在這里使用泛型類。 但是要回答您的問題,您可以這樣做(在一個單獨的類中):

public class Distance <T> {
    private T start;
    private T end;

    public boolean isPointWithinDistance(Object point){
        if (point.getClass().isAssignableFrom(LocalDateTime.class)){
            LocalDateTime localDateTime = (LocalDateTime) point;
            //do LocalDateTime logic
            //return resulting boolean
        }
        if (point.getClass().isAssignableFrom(Integer.class)){
            Integer integer = (Integer) point;
            // do Integer related business logic
            // return resulting boolean
        }else{
            throw new IllegalArgumentException("This method must be given either a LocalDateTime or Integer");
        }
    }
}

請注意,這種方法很快就會變得混亂。 從長遠來看,將所有這些保持分開和區分可能更有意義。

為此,我建議以下內容:

使用一個接口:

public interface Distance <T> {
    public boolean isPointWithinDistance(T point);
}

然后像這樣實現該接口:

整數:

public class IntegerDistance implements Distance<Integer> {
    private int start;
    private int end;

    public boolean isPointWithinDistance(Integer point){
        // do Integer related business logic
        // return resulting boolean
    }
}

LocalTimeDate:

public class LocalTimeDateDistance implements Distance<LocalDateTime> {
    private LocalDateTime start;
    private LocalDateTime end;

    public boolean isPointWithinDistance(LocalDateTime point){
        //do LocalDateTime logic
        //return resulting boolean
    }
}

接口的使用使您可以自由地定義兩者之間的重要關系(行為方面),並在編寫針對這兩種實現的不同方法時具有更大的靈活性(無需重寫)。

例如,在整數的情況下,您可能只希望起始和結束為正數。 在日期/時間的情況下,也許您會希望限制可以設置的開始和結束時間。 您可以在此示例中輕松設置唯一的setter。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM