混淆界面
本文关键字:界面 | 更新日期: 2023-09-27 18:12:48
我是c#新手。现在在阅读界面的时候。我很困惑。我在MSDN上读到,我们不能直接实例化接口。后来他们写了下面的例子:
Public interface ICat
{
meow();
}
Public class Cat : ICat
{
meow(){//do something }
}
////////////////////
static void main(){
Icat cat = new Cat();
Cat cat1 = nes Cat();
}
如果我们不能直接实例化接口,那么这一行的 Icat cat = new Cat();
的意义是什么?这两者的区别是什么?
这两行都实例化了Cat
类的实例。不同之处在于,其中一个被赋值给类型为ICat
的变量。
ICat cat = new Cat();
Cat cat1 = nes Cat();
因此,当通过cat
变量访问Cat
实例时,您只能调用在ICat
上声明的方法。当使用cat1
时,可以访问Cat
类的其他成员。
如果你在任何变量上调用GetType
,你将返回Cat
,因为这是你拥有的实例的类型。
另一个区别是,如果有另一个实现ICat
的类,你可以将它的实例分配给cat
变量,但你将无法将它分配给cat1
,除非它继承了Cat
:
Public class OtherCat : ICat
{
meow(){//do something }
}
cat = new OtherCat();
// cat1 = new OtherCat(); // fails
第一个示例中的接口没有被实例化,而是实例化的Cat()
实例的类型被声明为ICat
类型,而不是Cat
类型。
在你的特殊例子中,这不是很有趣。但是,考虑一个具有以下声明的接口:
public interface ICat
{
Meow();
Run();
Hunt();
}
一旦这个接口被应用到多个具体类型,行为就可以被应用到各种各样的类中,同时一致地实现相同的行为。
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();
两个具体实例都可以从接口保证的所有三种方法中受益,并且只能从接口保证的方法中受益,除非转换为它们的具体类型。这提供了跨行为的一致性。但是请注意,这并不是实例化接口。它只将具体实例分配给共享接口类型,这是语言允许的。
结果:
lion.Run();
和tiger.Run()
是完全允许的。
lion.Roar()
将无法编译,因为它不受接口的保证。也就是说,如果您转换为实际实例化并随后分配给接口的底层具体类型,那么除了接口的方法之外,您还可以访问该类型的方法。
((Lion)lion).Roar();
同样:
Lion concreteLion = new Lion();
在实例化时不分配给接口。因此,它可以直接访问接口保证的所有三个方法,并且它可以调用concreteLion.Roar()
而不需要强制转换,因为实例已直接分配给具体类型,而不是由Lion类实现的接口。
首先让我们来定义什么是interface
。
一个interface
可以被认为是一个契约,在这个意义上,一个类必须实现在给定接口(契约)内定义的任何东西。例如,假设我正在设计一个interface
来定义汽车的行为。
接口将包含两个关键行为。
public interface ICar
{
void Accelerate();
void Brake();
}
你永远不能实例化interface
,因为interface
只是一个契约,一个class
必须实现的定义,从interface
派生的class
将实现在它派生的interface
中定义的所有属性和方法。Interfaces
通常用于减少代码库中的依赖,如本答案所示。
继续上面的例子,人类驾驶汽车,但是有成千上万种不同的汽车,并且大多数汽车的实现方式不同,然而,这对人类来说应该无关紧要,如果你有能力驾驶一辆汽车,你应该能够驾驶所有的汽车。(这里只是概括一下,以保持简单)。
因此你需要做的是实例化一个class
,它实现了ICar
interface
,任何人都可以把它作为一个驱动器…
void Main()
{
Human jamesDoe = new Human();
ICar car = new BMW();
jamesDoe.TestDriveCar(car);
}
public interface ICar
{
void Accelerate();
void Brake();
}
public class BMW : ICar
{
private int x;
public void Accelerate()
{
new int[150].ToList()
.ForEach(i => { Console.WriteLine("{0} MPH", x++); Thread.Sleep(50); });
}
public void Brake()
{
new int[150].ToList()
.ForEach(i => { Console.WriteLine("{0} MPH", x--); Thread.Sleep(50); });
}
}
public class Human
{
public void TestDriveCar(ICar car)
{
car.Accelerate();
car.Brake();
}
}
我认为对我来说最好的描述是:
public interface IAnimal
{
void ShowVoice();
}
public class Cat : IAnimal
{
public void WiggleTail()
{
Console.Write("Wiggling tail...")
}
public void ShowVoice()
{
Console.Write("meow");
}
}
public class Dog : IAnimal
{
public void GivePaw()
{
Console.Write("Giving paw...")
}
public void ShowVoice()
{
Console.Write("woof");
}
}
public static void main(){
IAnimal cat = new Cat();
IAnimal dog = nes Dog();
cat.ShowVoice();
//cat.WiggleTail(); - cannot do that on interface
dog.ShowVoice();
//dog.GivePaw(); - cannot do that on interface
Cat catInst = new Cat();
Dog dogInst = new Dog();
catInst.WiggleTail(); // you can do that because it is not an interface that we make call to
dogInst.GivePaw(); //the same as with cat
// catInst.GivePaw(); - cannot do this because it does not exist in the class
}
定义接口时,定义泛型情况,当类实现该接口时,定义特定情况。以
为例interface IVehicle
{
int noOfWheels;
float price;
}
class TwoWheeler : IVehicle
{
public TwoWheeler(float price)
{
this.noOfWheels = 2;
this.price = price;
}
}
class FourWheeler : IVehicle
{
public FourWheeler(float price)
{
this.noOfWheels = 4;
this.price = price;
}
}
class VehicleBill
{
IVehicle vehicle;
public static void main()
{
Console.Write("enter your choice
'n 1. Two wheeler
'n 2. Four Wheeler");
int ch = Conver.toInt32(console.Read());
//Here we decide which class is to be used for initialization
if(ch == 1)
vehicle = TwoWheeler(80000);
else if(ch == 2)
vehicle = FourWheeler(500000);
}
}