【问题标题】:How to avoid redundant code for static methods如何避免静态方法的冗余代码
【发布时间】:2016-10-21 09:25:13
【问题描述】:

假设我有以下课程:

public class Cat {
    private final String noise = "meow";

    pulic static void makeNoise(){
        System.out.println(noise);
    }
}

public class Dog {
    private final String noise = "woof";

    pulic static void makeNoise(){
        System.out.println(noise);
    }
}

如您所见,这两个类共享几乎相同的代码。要删除冗余代码,我会创建一个这样的父类:

public abstract class Animal {
    protected final String noise;

    public Animal(String noise) {
        this.noise = noise;
    }      

    public void makeNoise() {
        System.out.println(noise);
    }
}

public class Dog extends Animal{
    public Dog(){
        super("woof");
    }
}

不幸的是,我遇到了两个问题:

  1. 既然使动物的噪音不再是静态的,作为常数 必须通过动物的构造函数分配,你会 需要创造一只猫或狗来获得该动物的噪音。甚至 虽然它是一个常数。
  2. 方法 makeNoise() 需要在 Animal 类中工作 - 它 默认情况下没有噪音。

一个可能的解决方案是这样的: 公共抽象无效 makeNoise(); 这既不允许,也不会消除将代码复制到 Animal 的每个孩子的需要。

您将如何消除动物子代中冗余代码的需要,同时保持方法 makeNoise 静态?

【问题讨论】:

  • 您的代码无法编译。不清楚为什么要保留方法static。不清楚你在问什么。
  • @saka1029 编辑被拒绝。不要妄下结论。
  • @EJP 上面的代码是一个数学类的简化版本。这个类包含各种函数来计算一些值。由于大多数这些函数都需要方法makeNoise(),我觉得有必要添加修饰符静态。这个类的实际子类添加了一些高级功能,并且对常量噪声有自己的价值:
  • 而且它不能编译,因为你的静态方法使用了一个非静态成员变量。由你来解决这个问题。我们无法了解您的实际意图。帖子偏离主题至少有两个原因。
  • @EJP 不要使用 us

标签: java oop static abstract


【解决方案1】:

Java 中的静态方法不能在子类中被覆盖。

如果您在子类中定义了与父类中的静态方法具有相同签名的静态方法,则该方法不会覆盖父方法,而是隐藏它。父类和子类中的方法没有任何关系。

在您的示例中,如果 Animal 中存在方法 static void makeNoise() 并且任何子类也定义了该方法,则子类只是将 makeNoise 方法隐藏在 Animal 中。

在您的示例中,您可以使用静态方法做的最好的事情是:

public static void makeNoise(String noise) {
    System.out.println(noise);
}

并以这种方式调用该方法:

Animal.makeNoise(Cat.NOISE); // A constant NOISE is defined in each subclass

如果方法makeNoise 是非静态的,则可以使用继承在每个子类中使用不同的噪声:

public abstract class Animal {
    protected String noise;

    protected Animal(String noise) {
        this.noise = noise;
    }

    public void makeNoise() {
        System.out.println(noise);
    }

}

public class Cat extends Animal{
    public static final String NOISE = "meow";

    public Cat() {
        super(NOISE);
    }
}

【讨论】:

  • 嗯,这不是我一直希望的,但至少我现在知道要走的路了。谢谢!
【解决方案2】:

为什么要用静态方法来表示现实世界的对象行为?每只动物都有自己的行为,所以你想区分它们。

 enum AnimalBehavior {
    MEOW, WOOF, ROAR
}

您可以使用包含所有动物行为的枚举。 还要考虑以下情况:狼在满月之夜不停地嚎叫。他一直这样做,直到他筋疲力尽。您想跟踪一个指示狼的能量水平的条形图。

private int energy = 100;

public static void wolfHowl() {
    System.out.println(AnimalBehavior.ROAR);
    energy = energy - 10;
}

这在技术上是行不通的,因为你使用的是静态方法。所以请记住你是如何设计你的东西的,因为那只狼实际上可以不累地嚎叫,直到有人真正生气为止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2013-06-14
    • 2012-11-17
    • 2019-01-02
    相关资源
    最近更新 更多