在 java 中创建界面对象
Creating interface objects in java
我遇到了一些Java代码:
public class LocationProvider {
public interface LocationCallback {
public void handleNewLocation(Location location);
}
// class constructor
public LocationProvider(Context context, LocationCallback callback){
...
}
}
我第一次在 Java 中遇到一个构造函数或方法,其参数是一个 "type" 接口。是否可以创建接口对象?你能像普通物品一样使用它们吗?
在 C++ 中,我知道不可能创建抽象对象 class。
您永远不会创建 "Class that is interface" 的对象。您可以创建一个实现接口的 class 对象,并将该对象作为参数传递给需要接口类型参数的方法。
好的。让我们回顾一下基础知识 :).
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。任何实现接口的 class 都被称为 该接口的 实例(在更广泛的上下文中)。
您将引用的类型与被引用对象的类型混淆了。
这是怎么回事
将 class 实例化为 对象 和具有给定类型的 引用 是两件不同的事情:
确实,您不能实例化接口。这意味着:
- 你不能调用
new MyInterface()
- 没有 object 将永远有一个类型
MyInterface
(请记住,我在这里谈论的是对象,而不是对它的引用)。
相反,reference 可以具有任何类型,该类型是它引用的对象类型的超类型。给定类型的超类型是:
- 对象的 class
的所有超classes
对象的class或其超classes
实现的所有接口
这称为类型的多重继承。
另一种查看方式:
- 无法实例化接口
- 但是接口是一个有效的类型
在代码中这意味着:
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
class 扩展了 Number
class 并实现了 Serializable
class :
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
的子类型,最终引用一个类型为 class 的对象,它实现了 LocationCallback
.
我遇到了一些Java代码:
public class LocationProvider {
public interface LocationCallback {
public void handleNewLocation(Location location);
}
// class constructor
public LocationProvider(Context context, LocationCallback callback){
...
}
}
我第一次在 Java 中遇到一个构造函数或方法,其参数是一个 "type" 接口。是否可以创建接口对象?你能像普通物品一样使用它们吗?
在 C++ 中,我知道不可能创建抽象对象 class。
您永远不会创建 "Class that is interface" 的对象。您可以创建一个实现接口的 class 对象,并将该对象作为参数传递给需要接口类型参数的方法。
好的。让我们回顾一下基础知识 :).
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。任何实现接口的 class 都被称为 该接口的 实例(在更广泛的上下文中)。
您将引用的类型与被引用对象的类型混淆了。
这是怎么回事
将 class 实例化为 对象 和具有给定类型的 引用 是两件不同的事情:
确实,您不能实例化接口。这意味着:
- 你不能调用
new MyInterface()
- 没有 object 将永远有一个类型
MyInterface
(请记住,我在这里谈论的是对象,而不是对它的引用)。
- 你不能调用
相反,reference 可以具有任何类型,该类型是它引用的对象类型的超类型。给定类型的超类型是:
- 对象的 class 的所有超classes
对象的class或其超classes
实现的所有接口这称为类型的多重继承。
另一种查看方式:
- 无法实例化接口
- 但是接口是一个有效的类型
在代码中这意味着:
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
class 扩展了 Number
class 并实现了 Serializable
class :
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
的子类型,最终引用一个类型为 class 的对象,它实现了 LocationCallback
.