我是C#的新手.现在在阅读Interfaces时.我很困惑.我在MSDN上读到我们无法直接实例化接口.后来他们写了下面的例子.
Public interface ICat
{
meow();
}
Public class Cat : ICat
{
meow(){//do something }
}
////////////////////
static void main(){
Icat cat = new Cat();
Cat cat1 = nes Cat();
}
Run Code Online (Sandbox Code Playgroud)
如果我们不能直接实例化Interfaces那么Icat cat = new Cat();这一行的含义是什么.那么这两者之间有什么区别?
这两行都实例化了一个Cat类的实例.不同之处在于其中一个被分配给输入的变量ICat.
ICat cat = new Cat();
Cat cat1 = nes Cat();
Run Code Online (Sandbox Code Playgroud)
因此,您只能通过变量ICat访问Cat实例时调用声明的方法cat.您可以Cat在使用时访问其他类成员cat1.
如果您调用GetType任何变量,您将Cat返回,因为这是您拥有的实例的类型.
另一个区别是,如果有另一个实现的类,ICat您可以将它的实例分配给cat变量,但cat1除非它继承,否则您将无法将其分配给Cat:
Public class OtherCat : ICat
{
meow(){//do something }
}
cat = new OtherCat();
// cat1 = new OtherCat(); // fails
Run Code Online (Sandbox Code Playgroud)
第一个示例中的接口未实例化,而是实例化Cat()实例的类型被声明为类型ICat而不是Cat.
在您的特定示例中,这不是很有趣.但是,请考虑具有以下声明的接口:
public interface ICat
{
Meow();
Run();
Hunt();
}
Run Code Online (Sandbox Code Playgroud)
将此接口应用于多个具体类型后,可以在各种类中应用行为,同时始终实现相同的行为.
public class Lion : ICat
{
public void Roar();
public void Meow();
public void Run();
public void Hunt();
}
public class Tiger : ICat
{
public void Meow();
public void Run();
public void Hunt();
}
ICat lion = new Lion();
ICat tiger = new Tiger();
Run Code Online (Sandbox Code Playgroud)
两个具体实例都可以受益于接口保证的所有三种方法,并且只有接口保证的方法,除非它们具体到它们的具体类型.这提供了跨行为的一致性.但请注意,这不是实例化接口.它只将具体实例分配给共享接口类型,这是语言允许的.
结果是:
lion.Run();并且tiger.Run()都是完全允许的.
然而,
lion.Roar()不会编译,因为接口无法保证.也就是说,如果您转换为实际实例化并随后分配给接口的基础具体类型,除了接口的方法之外,您还可以访问该类型的方法.
((Lion)lion).Roar();
Run Code Online (Sandbox Code Playgroud)
同样:
Lion concreteLion = new Lion();
Run Code Online (Sandbox Code Playgroud)
实例化时未分配给接口.因此,它可以直接访问接口保证的所有三种方法,并且可以concreteLion.Roar()在不需要强制转换的情况下调用,因为实例已直接分配给具体类型而不是Lion类实现的接口.