【问题标题】:Creating interface objects in java在java中创建接口对象
【发布时间】:2015-03-09 10:35:47
【问题描述】:

我遇到了一些Java代码:

public class LocationProvider {

   public interface LocationCallback {
      public void handleNewLocation(Location location);
   }

   // class constructor
   public LocationProvider(Context context, LocationCallback callback){ 
      ...
   }
}

在 Java 中,我第一次遇到带有“类型”参数的构造函数或方法,该参数是接口。是否可以创建接口对象?你能像普通对象一样使用它们吗?

我知道在 C++ 中创建抽象类的对象是不可能的。

【问题讨论】:

标签: java object interface


【解决方案1】:

您永远不会创建“作为接口的类”的对象。您可以创建实现接口的类的对象,并将该对象作为参数传递给需要接口类型参数的方法。

【讨论】:

  • 但是在这段代码中,LocationCallback 是一个接口
  • handleNewLocation 未实现。 ans 还声明了接口...我错过了什么?
  • @StefanBeike 蜘蛛侠、超人和幻影都应该能够做到这一点。但是请......不要用那种评论混淆人们!
  • 这意味着接口的实现实例应该作为参数传递在那里。
  • @Day_Dreamer LocationProvider 构造函数应该传递一个实现LocationCallback 接口的类的实例。
【解决方案2】:

好的。让我们回顾一下基础知识:)。

class A implements X{// where X is an interface
}

class B implements X{
}

现在,我们有

void someMethodAcceptingInterfaceX(X someInstanceOfX)
{
//do something
}

现在你可以做,

X a = new A();
X b = new B();
someMethodAcceptingInterfaceX(a);
someMethodAcceptingInterfaceX(b);

即,您可以传递 任何接口 X。任何实现接口的类都被称为该接口的实例(在更广泛的上下文中)。

【讨论】:

  • 也许这是另一个问题,但是:在 C++ 中,我知道接口具有纯虚拟方法。 “虚拟” - 因为它们必须由其他类实现,所以当它们的对象作为更通用的“接口类对象”传递给函数时,我们应该知道要运行哪个覆盖方法。在java中,即使在我给出的代码示例中,我也没有看到接口方法是虚拟的
  • @Day_Dreamer - 你使用的是哪个版本的 java?。答案可能会有所不同:P
  • 我不知道这个代码示例是哪个Java。在SO的某个地方找到它。存在哪些情况 - 我会检查你现在已经给了我足够的理解:)
  • "public void handleNewLocation(Location location);"是虚拟的。 :P
  • @Day_Dreamer - 好的。 关键字 abstract冗余。 :P。检查here。就像 yellen 所说,接口的方法是 implicitly virtual.. 你不必明确地将它们标记为 abstract :)
【解决方案3】:

您将引用的类型与被引用对象的类型混淆了。

发生了什么

将一个类实例化为一个对象和拥有一个给定类型的引用是两件不同的事情:

  • 确实,您无法实例化接口。这意味着:

    • 你不能打电话给new MyInterface()
    • object 永远不会有 MyInterface 类型(请记住,我在这里谈论的是对象,而不是对它的引用)。
  • 相反,reference 可以具有任何类型,它是它所引用的对象类型的超类型。给定类型的超类型是:

    • 对象类的所有超类
    • 对象的类或其超类实现的所有接口

      这称为类型的多重继承。

另一种看待方式:

  • 无法实例化接口
  • 但接口是有效类型

在代码中这意味着:

MyInterface i; // This is valid, only says that the type of i is MyInterface
i = new MyInterface(); // This is not valid, cannot instantiate the interface

您可以阅读有关引用类型和对象类型之间的区别here

示例

举个例子,Integer 类扩展了Number 类并实现了Serializable 类:

Integer i = new Integer(1); // The object referenced by i is of type Integer, forever
                            // i is a reference to that object,
                            // its type is a reference to Integer
Number n = i; // Now n is also referencing the same object.
              // The type of n is a reference to a Number. 
              // The referenced object hasn't changed, its type is still Integer
              // This is possible because Number is a supertype of Integer

Serializable s = i;  // Same, s is now referencing the same object.
                     // The object is still the same, its type hasn't changed
                     // The type of s is a reference to a Serializable.
                     // This is possible because Serializable is a supertype of Integer

适用于您的案例

构造函数定义

public LocationProvider(Context context, LocationCallback callback)

要求第二个参数是对LocationCallback 的引用。

这并不意味着被引用的对象应该是那种类型,事实上这是不可能的。这只意味着传递的引用应该是LocationCallback的子类型,最终引用的对象的类型是实现LocationCallback的类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2011-10-28
    相关资源
    最近更新 更多