我是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();
}
如果我们无法直接实例化接口,那么此行的 Icat cat = new Cat();
的含义是什么。
那两者之间有什么区别?
答案 0 :(得分:6)
两行实例化Cat
类的实例。区别在于其中一个被分配到变量为ICat
。
ICat cat = new Cat();
Cat cat1 = nes Cat();
因此,当您通过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
答案 1 :(得分:5)
第一个示例中的接口没有被实例化,而是实例化的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()
,因为实例已直接分配给具体类型而不是由实现的接口。狮子班。
答案 2 :(得分:1)
首先让我们来定义interface
是什么。
在类必须实现给定接口(契约)中定义的任何内容的意义上,interface
可以被认为与契约相同。例如,假设我正在设计一个interface
来定义汽车的行为。
界面将包含两个关键行为。
示例强>
public interface ICar
{
void Accelerate();
void Brake();
}
您永远无法实例化interface
,因为interface
只是一个合同,是class
必须实现的种类的定义,是class
派生的interface
将实现从其派生的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();
}
}
答案 3 :(得分:0)
我认为对我来说最好的描述是:
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
}
答案 4 :(得分:0)
当我们定义一个接口时,我们定义一个通用的情况,当一个类实现接口时,我们定义特定的情况。 让我们举个例子
print(mainMOC.hasChanges) //true
let persons = mainMOC.fetchAll(Person)
print(persons.count) //100