【发布时间】:2010-12-12 02:28:42
【问题描述】:
public class Foo : IFoo
...
有什么区别
IFoo foo = new Foo();
和
Foo foo = new Foo();
【问题讨论】:
-
C# 中有一些微妙之处,但在 Java 中没有涉及。请参阅我对乔恩回答的评论。
public class Foo : IFoo
...
有什么区别
IFoo foo = new Foo();
和
Foo foo = new Foo();
【问题讨论】:
区别仅在于变量的声明类型。每当您使用表达式foo 时,编译器都会使用该类型。例如,假设Foo 类包含一些在IFoo 中不 的方法。使用第一个声明,该成员将不可见 - 您必须将 foo 转换为 Foo 才能调用它。在第二个声明中,您可以直接访问它。
IFoo 的成员则相反,这些成员在 Foo 中使用 explicit interface implementation 实现。这相对很少见,但确实会发生。
使用第一个声明,您还可以将变量重新分配给对实现IFoo 类型的任何其他对象的引用,例如
foo = new SomeOtherIFooImplementation();
而对于第二个声明,您只能分配与Foo 兼容的值——即Foo 或派生类的实例。 (当然,在这两种情况下,您都可以将变量设置为 null。)
通常对接口而不是特定实现进行编码更有优势。这意味着编译器将阻止您使用特定于实现的细节,这反过来意味着将来更改为不同的实现可能会更容易。
变量的类型也会影响重载决议:
DoSomething(foo);
可能会调用不同的方法,具体取决于 foo 是声明为 Foo 还是 IFoo。
基本上,变量的编译时类型在各个方面都很重要 - 几乎每次使用变量时,该代码的某些含义都将取决于变量的类型。
【讨论】:
如果 foo 是 IFoo 类型,并且 Foo 实现了未在 IFoo 中定义的方法或属性,则除非将 foo 强制转换为 Foo,否则您将无法访问它们。
如果 foo 是 IFoo 类型,您可以实例化同样从 IFoo 继承的其他类型并将其分配给 foo。它更加抽象,因此您并不特别依赖于 Foo 类型。
【讨论】:
第一个例子是一些实现 IFoo 的对象的实例。 第二个例子是一个 Foo 对象的实例。
【讨论】: