在为两个相似类实现方法时是否可以避免重复代码?

时间:2018-05-06 07:57:00

标签: java overloading

我有两个课程:FishPlant。它们不会从任何类继承。

但是他们都有一个名为isAlive()的方法具有相同的实现细节。现在我有一份鱼和另一份狗的名单,我需要清除死鱼和死狗。我希望我的方法具有相同的名称,但如果不向方法签名添加其他字段则无法实现。是否有可能我不需要编写与最后一块代码相同的额外代码块?

以下是代码。对于课程ModelFishPlant是两个数据成员,它们是FishPlant个对象的ArrayList。

有什么方法可以只编写一个名为count的方法,我不需要在方法签名中添加额外的字段或修改我的返回类型吗?

public class Fish{
    public boolean isAlive(){
        if(this.size > 0){
            return true;
        }
        return false;
    }
}
public class Plant{
    public boolean isAlive(){
        if(this.size > 0){
            return true;
        }
        return false;
    }
}

public class Model{
    private int countDeadFish() {
        int totalCount = 0;
        for(Fish aFish : this.fish) {
            if(aFish.isAlive() == false) {
                totalCount += 1;
            }
        }
        return totalCount;
    }

    private int countDeadPlants() {
        int totalCount = 0;
        for(Plant plant : this.plants) {
            if(plant.isAlive() == false) {
                totalCount += 1;
            }
        }
        return totalCount;
    }
}

5 个答案:

答案 0 :(得分:2)

如果您不想使用继承,则可以使用常用方法:

public class AliveChecker {

    public static boolean isAlive(int size) {
        return size > 0;
    }

}

public class Plant{
    public boolean isAlive(){
        return AliveChecker.isAlive(this.size);
    }
}

public class Fish{
    public boolean isAlive(){
        return AliveChecker.isAlive(this.size);
    }
}

答案 1 :(得分:1)

由于FishPlant不从任何东西继承,您可以考虑创建一个超类并从中扩展:

public class LivingThing {
    protected int size = 1;
    public boolean isAlive() {
        return size > 0;
    }
}

public class Plant extends LivingThing {
}

public class Fish extends LivingThing {  
}

此示例使用inheritancePlantFish归类为超类LivingThing。例如,您可以在size的构造函数或实例方法中设置Plant

public class Plant extends LivingThing {
    public Plant(int size){
        this.size = size;
    }
}

您的Model可能是:

public class Model{
    private int countDeadFish() {
        return countDead(this.fish);
    }

    private int countDeadPlants() {
        return countDead(this.plants);
    }

    private int countDead(ArrayList<LivingThing> things) {
        int totalCount = 0;
        for(LivingThing thing: things) {
            if(!thing.isAlive()) {
                totalCount++;
            }
        }
        return totalCount;
    }
}

答案 2 :(得分:0)

您可以创建一个实用工具方法(在某个地方的实用程序class中):

public final class Liveliness {

    private Liveliness() {
    }

    public static boolean isAlive(final IntSupplier sizer) {
        return sizer.getAsInt() > 0;
    }

}

然后你的方法变成:

public boolean isAlive(){
    return Liveliness.isAlive(this::getSize);
}

或者,使用interface Life

public interface Life {

    int getSize();

    default boolean isAlive(){
        return getSize() > 0;
    }
}

这样,添加getSize方法并从Life继承将添加该方法。

注意,请避免以下反模式:

if(test) {
    return true;
} else {
    return false;
}

使用return test

答案 3 :(得分:0)

使用界面

public interface LiveObject {
    boolean isAlive();
}

public class Fish implements LiveObject {
    public boolean isAlive(){
        if(this.size > 0){
            return true;
        }
        return false;
    }
}

public class Plant implements LiveObject {
    public boolean isAlive(){
        if(this.size > 0){
            return true;
        }
        return false;
    }
}

public class Model{

    private int countDead(Collection<LiveObject> objects) {
        int totalCount = 0;
        for(LiveObject obj : objects) {
            if(obj.isAlive() == false) {
                totalCount += 1;
            }
        }
        return totalCount;
    }

    private int countDeadFish() {
        return countDead(this.fish);
    }
}

答案 4 :(得分:0)

根据评论,您似乎无法修改FishPlant。这是一种减少countDead<Something>方法中重复的方法,不需要这样做。

基本上,您希望计算满足特定条件的数组中的项目。使用Java 8,您可以使用lambdas或方法引用在谓词中捕获此条件。您不需要为此继承或实现某个接口。

private long countDeadFish() {
    return countDeadItems(this.fish, Fish::isAlive);
}

private long countDeadPlants() {
    return countDeadItems(this.plants, Plant::isAlive);
}

private <T> long countDeadItems(Collection<T> items, Predicate<? super T> isAlive) {
    return items.stream().filter(isAlive.negate()).count();
}