【问题标题】:In Java polymorphism, can all the classes that implements an interface be created as that type interface?在Java多态中,是否可以将所有实现接口的类都创建为该类型接口?
【发布时间】:2016-02-21 08:15:57
【问题描述】:

当我继续我的在线教程时,我遇到了这个课程。我有一个接口和两个实现该接口的类。

public interface Payable {
double getPaymentAmount();
}

  • 实现上述接口Payable的类Invoice
  • SalariedEmployee扩展了一个抽象类Employee,它实现了Payable接口。
  • 一个测试类,包含测试它的主要方法。

现在在测试类中,当创建一个对象数组时,对象的类型被称为Payable[]而不是SalariedEmployee[]Invoice[],就像

    public static void main(String[] args) {
    Payable[] payableObjects = new Payable[4];
    payableObjects[0] = new Invoice("0000", "abc", 1,2);
    payableObjects[1] = new SalariedEmployee("test", "user", "000-000", 35);
  • 是不是因为所有的类都实现了Payable[]接口?
  • 如果接口定义在顶层层次结构中,是否总是可以创建实现该接口的所有类的对象?

【问题讨论】:

  • 1.是的,如果不是这样,你会得到一个编译器错误。 2. 是的,以ListMap 为例,您应该始终将变量声明为ListMap 以便能够更改分配类类型。您的一般用例是,您只想调用此特定接口提供的方法。
  • 谢谢@KevinEsche。请把它作为答案发布,我会接受的。
  • 是的,这就是多态性的全部意义所在。

标签: java interface polymorphism super implements


【解决方案1】:

您的问题标题不符合语法,但单词选择表明存在对概念的微妙误解。

您只能创建一个类作为该类。也就是说,您不能编写 new Payable 并以某种方式期望创建任何 InvoiceSalariedEmployee 对象。

但是您可以引用Payable 指向任何实现Payable 的对象。这就是子类型多态的基本思想。

示例中发生的情况是创建了一个包含四个 Payable 引用的数组。这些引用还没有指向任何东西(它们是空的)并且周围还没有 InvoiceSalariedEmployee 对象,只有数组对象。

然后,代码创建两个对象并将它们分配给两个引用。这与数组元素是自变量一样工作。 (几乎,但差异是由于数组协方差,这在这一点上并不重要。)特别是,new 运算符的结果在第一种情况下具有类型Invoice,而不是Payable。您可以将 Invoice 分配给 Payable 引用,但转换发生在分配时,而不是在创建时。

所以从技术上讲,您的标题问题的答案是“不,对象总是按照您在 new 表达式中指定的类型创建,但您可以在之后转换引用”。

【讨论】:

    【解决方案2】:

    对于您的第一个问题:是的,如果不是这样,您会收到编译器错误。

    对于第二种情况,以ListMap 为例。看下面的例子。我们声明了一个列表,但根据标志,我们希望这个特定的 List 表现不同,因为它代表不同的类

    public class BookList{
        List <String> list;
    
        public BookList(boolean flag) {
            if(flag) {
                list = new ArrayList<>();
            } else {
                list = new LinkedList<>();
            }
        }
    }
    

    由于我们将其声明为List,因此我们能够分配实现此interface 的不同类型的列表。您可以非常简单地更改此类的用例,同时您仍然可以访问接口提供的每个方法。

    这也是您的Payable 数组正在做的事情。你想将不同类型的类分配到这个数组中,它们都实现了这个接口。

    这将使为这个特定接口创建方法变得更加容易。以求和方法为例。

    public int sumPayable(Payable[] payables) {
        int sum = 0;
        for(Payable p : payables) {
            sum += p.getPaymentAmount();
        }
        return sum;
    }
    

    在这种情况下,实现Payable 的每个类的实际类是什么并不重要,因为您可以像创建时一样简单地将数组传递给该方法。

    【讨论】:

    • 谢谢@Kevin。我还没有遇到过这个&lt;String&gt; 运算符。它是做什么用的,它叫什么?如果你能给我一个术语来查找,我会谷歌它。
    • @scott 这些是Generics
    猜你喜欢
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 2013-02-24
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多