【问题标题】:java static methods and interfaces/inheritancejava静态方法和接口/继承
【发布时间】:2015-12-01 12:31:35
【问题描述】:

好的,所以我有一个类和子类的层次结构。 他们都必须有一定的方法。这些方法位于由超类和下面的所有内容实现的接口中。

他们都应该拥有并定义一种方法,但该方法是“精神上的”,属于静态类型,为给定类的所有实例返回相同的结果。

不幸的是,不能将静态方法作为接口的一部分,而且静态方法不支持继承,它们“隐藏”而不是“覆盖”。

那么,层次结构中的所有类都必须具有并且可以以通用方式调用的静态方法有哪些选项?目前,我将该方法设为非静态的......

此外,理想情况下,这不应该涉及第二个类的层次结构,该层次结构必须仅针对该一种方法保持同步......

非常感谢

======

编辑:人们要求举个例子,所以你去:

好的,假设我有一个动物类的层次结构(抽象动物类>抽象哺乳动物类>猫类、狗类、海豚类等)。 一些行为将是特定于实例的,它们可能有“weight”、“name”、“age”等成员,并有相关的 getter/setter。

但是,可能有一种方法通常会为给定类的所有实例提供相同的结果,例如它可能是其中之一:

-int getNumberOfLegs();
-String getFavouriteFood();

所有的猫都有 4 条腿,所以方法可以是静态的,它不依赖于实例。它更像是元信息。我希望能够做 Cat.getNumberOfLegs()。我想以一种可以被覆盖的方式强制该方法在我的所有层次结构中存在,等等。

【问题讨论】:

  • 如果你想得到正确的答案,你需要举一个真实的例子。
  • 一个例子可以很好地说明您的潜在需求,而不仅仅是技术方面。
  • 提供一些你正在尝试做的简短代码
  • 我添加了一个例子。谢谢。

标签: java inheritance static


【解决方案1】:

虽然如果你能用例子来支持你的问题会更好。据我了解,您希望子类为某些方法编写自己的行为 - 因此您需要覆盖。因此,这种方法可能不是静态的候选方法。可能你能做的最好的事情就是拥有一个抽象类。如果您真的坚持,请提供默认实现。或者只是确保每个子类都定义它。为此,将方法本身设为抽象。

编辑后: 引用你的话:

我想以一种可以被覆盖的方式强制在我的所有层次结构中存在该方法,等等。

上面清楚地表明您需要摘要。不是静态的。

-int getNumberOfLegs();
-String getFavouriteFood();

对于海豚和狗来说应该是不同的。因此,您无法通过静态方法来做到这一点。静态方法可以用于你的 mammel 类,它可以有类似的东西

String getMyNature {
    // return Mammel nature
}

静态必须是类级别。但是由于您希望使用相同的接口来访问特定于实例的信息,因此您必须使用抽象(强制每个实现都拥有它)。

【讨论】:

  • 我添加了一个例子。谢谢。
  • 但是,在给定的类中,方法总是给出相同的值,而与任何实例无关。 Cat 类有许多 cat 实例,但它们都有 4 条腿,因此可以静态调用此方法。当涉及整个班级而不是特定实例时,最喜欢的食物或任何其他行为也是如此。我的意思是这可能只是语言的限制。其他语言支持接口中继承的静态/类方法。很想看到好的 java 变通方法。
  • 那么你可以在每个子类中使用静态方法。但静态方法不能被覆盖。那么你对通用接口的要求就无法满足
【解决方案2】:

除了Animal 中的抽象方法之外,该方法将在每个类中被覆盖以提供类似的常量值

class Cat extends Animal {
    private static final int NUMBER_OF_LEGS_ON_A_CAT = 4;

    @Override
    public int getNumberOfLegs() {
        return NUMBER_OF_LEGS_ON_A_CAT;
    }
}

你也可以在你的超类中创建非抽象方法,并通过超级构造函数提供常量,如下所示:

class Animal {
    private final int numberOfLegs;

    protected Animal(int numberOfLegs) {
        this.numberOfLegs = numberOfLegs;
    }        

    public final int getNumberOfLegs() {
        return numberOfLegs;
    }
}

class Cat extends Animal {
    private static final int NUMBER_OF_LEGS_ON_A_CAT = 4;

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

这种方法可能不那么冗长,但另一方面,如果这样的常量太多,可能会变得非常不可读。


然而,最重要的是静态方法和子类型不能很好地结合在一起,所以你能做的最好的可能是使方法非静态并确保它返回的数据是静态的——这是通过提供一个通过构造函数将常量转换为最终字段,通过在覆盖方法中返回一个常量等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-07
    • 2014-03-03
    • 2016-10-06
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2010-11-10
    • 2012-12-23
    相关资源
    最近更新 更多