Gau*_*123 12 c# interface class
我有一个类,CustomerNew和一个接口,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();
}
Run Code Online (Sandbox Code Playgroud)
我对这两行代码感到很困惑.
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
Run Code Online (Sandbox Code Playgroud)
第一行代码意味着我们正在传递CustomerNew类的对象引用objnew,我是否正确?如果是,那么为什么我不能访问类的方法B()interface objnew?
有人可以详细解释这两个.
ang*_*son 28
接口有许多功能和用途,但一个核心问题是能够在商定的合同中向外界提供功能.
让我给你举个例子.考虑一个汽水自动售货机.它有一个或两个插槽供您输入硬币,一些按钮供您选择正确类型的苏打水和一个按钮来分配苏打水(除非选择按钮也这样做).
现在,这是一个界面.这隐藏了界面背后的机器的复杂性,并为您提供了一些选择.
但是,这里是重要的部分,机器内部具有很多功能,它甚至可能有其他按钮和旋钮,通常用于维护人员在出现问题时测试或操作机器,或者他们必须把它倒空或用苏打水填充.
机器的这一部分对您是隐藏的,您只能访问添加到该接口的外部接口的创建者.
你甚至不知道机器在幕后实际运作.我可以创建一个新的自动售货机,从附近的工厂传送苏打水,并将你直接添加的硬币传送到银行,你就不会更聪明了.更不用说我会变得富有,但这是另一个故事.
所以,回到你的代码.
你明确声明objnew为ICustomer.无论你在这个界面背后隐藏什么.您只能访问声明为该接口一部分的任何内容.
另一个变量被声明为具有底层对象的类型,因此您可以完全访问其所有公共功能.可以把它想象成解锁自动售货机并在前面打开时使用它.
在第一行:
ICustomer objnew
Run Code Online (Sandbox Code Playgroud)
您可指示编译器把objnew作为ICustomer而且由于接口不声明B()方法,它的错误.
在第二行:
CustomerNew objCustomerNew
Run Code Online (Sandbox Code Playgroud)
你指的是objCustomerNewas CustomerNew,因为它确实指定了一个B()方法,它编译得很好.
实际上,接口也是一种类型(您不能创建接口实例,因为它们只是元数据).
由于CustomerNew工具ICustomer的一个实例CustomerNew可以upcasted到ICustomer.当CustomerNew键入作为ICustomer你只能访问ICustomer成员.
这是因为C#是一种强类型语言,因此,为了访问特定成员(即方法,属性,事件......),您需要通过定义要访问的成员的类型来限定对象引用.(即您需要将CustomerNew对象存储在类型的引用中CustomerNew以访问该方法B).
OP说:
因此,由于向上转换,我们只能访问界面内部的那些方法,对吗?UPCASTING背后的主要原因是什么?
是.一个简单的解释是一个ICustomer不应强制执行的对象CustomerNew.您需要向下转换的ICustomer参考CustomerNew,以便能够访问CustomerNew成员.
由于类和接口都是类型,而C#是强类型语言,因此可以通过提供实际类型来访问对象成员.这就是你需要使用演员表的原因.
例如,您的代码执行隐式upcast:
// This is an implicit cast that's equivalent to
// ICustomer objnew = (ICustomer)new CustomerNew()
ICustomer objnew = new CustomerNew();
Run Code Online (Sandbox Code Playgroud)
隐upcasts是可能的,因为编译器已经知道CustomerNew器具ICustomer反思CustomerNew的元数据,虽然你不能implictly- 垂头丧气一个ICustomer参考,因为谁知道谁实现ICustomer?它可以是CustomerNew任何其他类,也可以是结构:
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;
Run Code Online (Sandbox Code Playgroud)
如果您不确定ICustomera CustomerNew是否为a ,则可以使用as运算符,如果无法进行强制转换,则不会在运行时抛出异常:
// If asInterface isn't also a CustomerNew, the expression will set null
CustomerNew asClass3 = asInterface as CustomerNew;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1749 次 |
| 最近记录: |