我需要和你讨论一件事。我一直在阅读有关接口的信息,它是类之间的契约接口,该类将提供接口的所有方法的实现。为了解决着名的钻石问题,我们有接口。 喜欢(我正在使用C#)
public interface IAInterface
{
void aMethod();
}
public interface IBInterface
{
void aMethod();
}
现在
public class aClass : IAInterface, IBInterface
{
public void aMethod()
{
}
}
通过上面的代码,据说aClass提供了接口方法的实现。我的困惑是:如果它是类和接口之间的契约,那么我们怎么能说与两个接口的契约都得到满足呢?
一个现实世界的例子, 就像我和杰克订的那样,我会同时给他5美元,我也和Ben签了合同我会给他5美元,现在给他们中的一个(杰克或本)提供5美元我怎么说我和他们两个都履行了合同?
我的问题似乎很幼稚,但这让我很困惑。
答案 0 :(得分:9)
接口保证将实现一组给定的方法。该接口不关心如何实现代码。与扩展类相反,当您扩展类时,您正在使用一些预定义的代码。
如果使用相同的方法扩展两个类,比如methodA
,并调用此方法,则编译器将不知道它需要运行哪个类。另一方面,当您使用相同的方法实现两个接口时,由于实现是在您自己的代码中编写的,因此编译器将知道在哪里找到实现。
所以基本上,当你实施某些东西时,你保证会提供一些服务。
编辑:我会尝试并以一些面向对象的方式转换它,希望能让事情更清晰。
杰克和本将保证他们会借给你钱,另一方面,你保证会还钱,因此,从OO的角度来看,你可以这样看:
public interface IPay
{
public void Pay(Individual i);
}
public class MySelf : IPay
{
public void Pay(Individual i)
{
...
}
}
public interface ILend
{
public void Lend(Individual i);
}
public class Jack : ILend //Same applies for Ben
{
public void Lend(Individual i)
{
...
}
}
这就是我要解决您指定的问题的方法。
至于其他垃圾的例子,你可以这样做:
public interface ITakeTrash
{
public void TakeTrash(Trash t);
}
public Son : ITakeTrash
{
public void TakeTrash(Trash t);
}
public class Mum //Same applies for dad
{
Son mySon = ...
mySon.TakeTrash(t);
}
你的母亲和父亲都不知道如何处理垃圾,但是,他们知道你知道如何处理它,这就是他们关心的事情(就像上面一样,你只关心Ben和Jack可以给你钱,而其他各方只关心你可以还钱,所涉及的真的 非常关心你是怎么做的。
我确实理解你要去的地方,基本上说如果我使用具有相同名称的方法实现两个不同的接口,那么会做什么。如果你最终遇到这种情况,我认为这可能是由于糟糕的设计。我不建议建立一个能完成各种不同事情的单一课程,这也是其中一个原因。
另一方面,您可能会问,如果我有2个接口使用相同名称的方法做类似的事情怎么办?然后,我认为答案是,因为接口做类似的事情,并且你有相同名称的方法,所以很可能你做的是同样的事情,因此,你不需要让自己迷惑。
我希望这次编辑有助于解决这个问题。
答案 1 :(得分:4)
好的实施方法不像给钱。这就像取出垃圾一样。如果你答应妈妈和爸爸取出垃圾,就可以把垃圾拿掉一次。
答案 2 :(得分:1)
作为一个例子,我们有两个接口,它们都具有相同的功能PrintIt,而MyClass类实现了两个接口。
interface IAInterface
{
void PrintIt(string s);
}
interface IBInterface
{
void PrintIt(string s);
}
class MyClass : IAInterface, IBInterface
{
public void PrintIt(string s)
{
Console.WriteLine(s);
}
}
您可以通过
引用多个界面 MyClass _class = new MyClass();
_class.PrintIt("Class");
IAInterface _aInterface = (IAInterface)_class;
_aInterface.PrintIt("IAInterface");
IBInterface _bInterface = (IBInterface )_class;
_bInterface.PrintIt("IBInterface");
您还可以提供明确的接口实现......
class MyClass : IAInterface, IBInterface
{
public void IAInterface.PrintIt(string s)
{
Console.WriteLine("AInterface - {0}", s);
}
public void IBInterface.PrintIt(string s)
{
Console.WriteLine("BInterface - {0}", s);
}
}
答案 3 :(得分:0)
由于两种方法具有相同的名称和相同的签名(意味着相同的返回值类型和相同的参数定义),因此假设两种方法都相同。
答案 4 :(得分:0)
在多重继承中,使用时会出现钻石问题,
public class A
{
public virtual void aMethod();
}
public class B
{
public virtual void aMethod();
}
现在
public class aClass : A, B
{
public override void aMethod()
{ }
}
在上面的代码中,对于aClass,将为 vTable 中的相同aMethod()创建两个 vPtr 。因此出现歧义(钻石概率)
但是当你使用接口时,没有vTable的概念出现。因为vTable在基类和派生类场景之间用于调用它们之间的diff实现是有用的。在这种情况下,接口不会包含任何实现,因此没有vPtr,vTable,因此没有钻石问题。
答案 5 :(得分:0)
如果必须从不同的接口实现相同的命名方法。试试这个。
interface IFoo
{
void SayHello();
}
interface IBar : IFoo
{
new void SayHello();
}
class myFooBarImp : IFoo, IBar
{
void IFoo.SayHello()
{
Console.WriteLine("Hello from IFoo implementation");
}
void IBar.SayHello()
{
Console.WriteLine("Hello from IBar implementation");
}
public void SayHello()
{
Console.WriteLine("Hello from SayHello");
}
}
class Program1
{
public static void Main()
{
myFooBarImp obj = new myFooBarImp();
obj.SayHello();
(obj as IFoo).SayHello();
(obj as IBar).SayHello();
return;
}
}
答案 6 :(得分:0)
父类设计为由子类使用,而接口设计为由子类实现。因此,即使两个父接口的方法相同,继承它也不会对子类造成混淆。
参考:https://dotnettutorials.net/lesson/multiple-inheritance-csharp/