我有两个课程:Fish
和Plant
。它们不会从任何类继承。
但是他们都有一个名为isAlive()
的方法具有相同的实现细节。现在我有一份鱼和另一份狗的名单,我需要清除死鱼和死狗。我希望我的方法具有相同的名称,但如果不向方法签名添加其他字段则无法实现。是否有可能我不需要编写与最后一块代码相同的额外代码块?
以下是代码。对于课程Model
,Fish
和Plant
是两个数据成员,它们是Fish
和Plant
个对象的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;
}
}
答案 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)
由于Fish
和Plant
不从任何东西继承,您可以考虑创建一个超类并从中扩展:
public class LivingThing {
protected int size = 1;
public boolean isAlive() {
return size > 0;
}
}
public class Plant extends LivingThing {
}
public class Fish extends LivingThing {
}
此示例使用inheritance将Plant
和Fish
归类为超类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)
根据评论,您似乎无法修改Fish
或Plant
。这是一种减少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();
}