我有一个类CustomerNew
和一个接口(interface)ICustomer
:
public class CustomerNew : ICustomer
{
public void A()
{
MessageBox.Show("Class method");
}
void ICustomer.A()
{
MessageBox.Show("Interface method");
}
public void B()
{
MessageBox.Show("Class Method");
}
}
public interface ICustomer
{
void A();
}
我对这两行代码感到非常困惑。
ICustomer objnew = new CustomerNew();
CustomerNew objCustomerNew = new CustomerNew();
objnew.B(); // Why this is wrong?
objCustomerNew.B(); // This is correct because we are using object of class
代码的第一行表示我们正在
objnew
中传递CustomerNew类的对象引用,对吗?如果是,那么为什么我不能使用interface objnew
访问该类的方法B()?有人可以详细解释这两个问题吗?
最佳答案
实际上,接口(interface)也是一种类型(您不能创建接口(interface)实例,因为它们只是元数据)。
由于CustomerNew
实现ICustomer
,因此可以将CustomerNew
的实例上载到ICustomer
。当将CustomerNew
键入为ICustomer
时,您只能访问ICustomer
成员。
这是因为C#是一种强类型语言,因此,为了访问特定的成员(即方法,属性,事件...),您需要一个对象引用,该对象引用必须通过定义要访问的成员的类型来限定(即,您需要将CustomerNew
对象存储在CustomerNew
类型的引用中,以访问B
方法)。
更新
OP说:
是的。一个简单的解释是实现ICustomer
的对象不应该强制为CustomerNew
。您需要将对ICustomer
的CustomerNew
引用下调到CustomerNew
才能访问CustomerNew
成员。
由于类和接口(interface)都是类型,并且C#是强类型语言,因此您可以通过提供对象的实际类型来访问对象成员。这就是为什么您需要使用强制转换。
例如,您的代码进行了隐式转换:
// This is an implicit cast that's equivalent to
// ICustomer objnew = (ICustomer)new CustomerNew()
ICustomer objnew = new CustomerNew();
隐式上报是可能的,因为编译器已经知道
ICustomer
实现了对CustomerNew
元数据进行内省(introspection)的ICustomer
,而您又不能隐式下传ICustomer
引用,因为谁知道谁实现了CustomerNew
?它可以是ICustomer
或任何其他类甚至是一个struct:ICustomer asInterface = new CustomerNew();
// ERROR: This won't compile, you need to provide an EXPLICIT DOWNCAST
CustomerNew asClass1 = asInterface;
// OK. You're telling the compiler you know that asInterface
// reference is guaranteed to be a CustomerNew too!
CustomerNew asClass2 = (CustomerNew)asInterface;
如果不确定
CustomerNew
是as
,则可以使用ojit_code运算符,如果无法进行强制转换,该运算符在运行时不会引发异常:// If asInterface isn't also a CustomerNew, the expression will set null
CustomerNew asClass3 = asInterface as CustomerNew;
关于c# - OOPS概念: What is the difference in passing object reference to interface and creating class object in C#?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30570185/