在Java多态中,是否可以将实现接口的所有类创建为该类型接口?

时间:2015-11-19 09:18:53

标签: java interface polymorphism super implements

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

public interface Payable {
double getPaymentAmount();
}

  • Invoice,用于实现上述接口Payable
  • 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 []?
  • 接口
  • 如果在顶级层次结构中定义了接口,是否始终可以创建实现该接口的所有类的对象?

2 个答案:

答案 0 :(得分:4)

你的问题标题不是语法,但选择一词表明对概念的细微误解。

您只能创建一个类作为该类。也就是说,您无法编写new Payable,并且不知何故可能会创建任何InvoiceSalariedEmployee个对象。

但是你可以引用Payable指向任何实现Payable的对象。这几乎是亚型多态性的基本思想。

示例中的内容是创建了四个Payable引用的数组。这些引用尚未指向任何内容(它们为空)并且还没有InvoiceSalariedEmployee个对象,只有数组对象。

然后,代码创建两个对象并将它们分配给两个引用。这与数组元素是独立变量的情况相同。 (差不多,但不同之处在于数组协方差,此时这并不重要。)特别是new运算符的结果在第一种情况下的类型为Invoice,而不是{ {1}}。您可以将Payable分配给Invoice引用,但转换是在分配时进行的,而不是在创建时进行的。

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

答案 1 :(得分:1)

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

对于第二种情况,请以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的每个类的实际类都是无关紧要的,因为你可以简单地将一个数组传递给这个方法,就像你创建的那样。