When I type objects is there any difference between me using an Interface or a class?
我创建了这个界面:
1 2 3 4 5 6 7 8 9 | public interface IPhrase { int CategoryId { get; set; } string PhraseId { get; set; } string English { get; set; } string Romaji { get; set; } string Kana { get; set; } string Kanji { get; set; } } |
这门课:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Phrase : IPhrase { public Phrase() { } public int CategoryId { get; set; } public string PhraseId { get; set; } public string English { get; set; } public string Romaji { get; set; } public string Kana { get; set; } public string Kanji { get; set; } } |
号
在此,此代码返回数据并将其类型转换为短语:
1 2 | var phrases = db2.Query<Phrase>("SELECT * FROM Phrase", ans); var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans); |
我想知道的是,我在这里使用
接口是一个保证的契约,任何实现接口的类都将实现接口中定义的方法和属性。这允许您使用接口创建方法、列表等,这些方法、列表等接受实现接口的任何类,例如
1 2 3 4 5 6 7 8 9 10 | public interface IExample { int GetInt(); } public void ProcessInt(IExample value) { var tempInt = value.GetInt(); // Do processing here } |
这允许将实现接口iexample的任何具体类传递给此方法。该方法可以确保传递的任何具体类都将实现getint方法。
对于对象,可以从继承到:
对象
如果你有一个
有了对象继承,我们可以想到一个短语:
接口
通过一个接口,您可以把它看作是该对象的描述器。如
所以想想这个短语:
现在,为了回答您的问题,如果您使用接口或不使用接口,会有什么不同吗?
嗯,在这种情况下不会,但是如果你扩展你的短语并创建一个
您还可以在短语中应用一个名为
我发现接口最有用的地方是在统一中注册不同类型。
其中会产生影响:
如果对象上有一个不在接口上的属性,那么如果您返回接口,那么除非您键入cast,否则您将无法很容易地访问该属性。
如:
1 2 3 4 5 6 7 8 9 10 | public class Phrase : IPhrase { public Phrase() { } public int CategoryId { get; set; } public string PhraseId { get; set; } public string English { get; set; } } |
。
和接口
1 2 3 4 | public interface IPhrase { int CategoryId { get; set; } } |
。
如果返回接口,将无法访问属性English:
1 2 | var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans); var eng = phrases[0].English; //**THIS WONT WORK** |
在本地使用接口和具体对象之间没有区别,如您的示例中所示。主要的区别在于,当您在API或构造函数参数中发送接口与具体类作为参数时,其中最好使用接口,以便实现解耦和可测试性。
尽管如此,对于您的问题,简短的回答是"否",没有区别,您是否希望使用接口或具体对象作为局部变量是您自己的选择(您似乎更容易阅读)。不要忘记字段和属性很好地声明为接口,这样可以提供更大的灵活性。
当使用一个具体的对象而不是一个接口(甚至在本地)时,最后一件应该考虑的事情是,你可能希望有一天改变方法的签名,这个方法提供给你这个对象返回另一种实现相同接口的对象,在这种情况下,你也应该改变本地变量(即使它是n哦,太糟糕了,而且很少发生,我不得不注意它),如下面的例子所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | interface IAnimal { void Run(); } class Cat : IAnimal { public void Run() { //... } } class Dog : IAnimal { public void Run() { //... } } |
号
如果您的代码中有一个方法返回您使用的
1 2 3 4 5 6 7 | Cat GetAnimal() { return new Cat(); } Cat myAnimal = GetAnimal(); //note that here it is expected a Cat myAnimal.Run(); |
然后,如果更改
1 2 | Dog myAnimal = GetAnimal(); //note that here it is expected a Cat myAnimal.Run(); |
。
但是,如果您使用的是接口,那么当方法的签名ar发生更改时,您的代码就不太可能需要更改:
1 2 | IAnimal myAnimal = GetAnimal(); //this is working whether a Cat or a Dog is received. myAnimal.Run(); |
但这种情况再次发生的可能性相对较小。为愚蠢的猫和狗的例子道歉!
你的答案取决于你想如何使用你未来的课程。接口是契约,以确保子类具有接口的所有定义。所以当您想要使用多态性时,这是很有用的。通过这种方式,您可以在接口类中定义对象的所有公共规范。接口的另一个优点是您的类可以从多个接口继承,这对于C中的其他类型的类是不允许的。下面是一个示例代码。希望对你有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | public interface IShape { float Area { get; } float circumference { get; } } public class Rectangle : IShape { private float l, h; public Rectangle( float length, float height ) { l = length; h = height; } public float Area { get { return l * h; } } public float circumference { get { return ( l + h ) * 2; } } } public class Circle : IShape { private float r; public Circle( float radius ) { r = radius; } public float Area { get { return (float)Math.PI * r * r; } } public float circumference { get { return (float)Math.PI * r * 2; } } } public class SomeClass { IShape[] shapes = new IShape[] // Can store all shapes regardless of its type { new Rectangle( 10f, 20f ), new Rectangle( 15f, 20f ), new Rectangle( 11.6f, .8f ), new Circle( 11f ), new Circle( 4.7f ) }; public void PrintAreas() { foreach ( var sh in shapes ) Console.WriteLine( sh.Area ); // prints area of shape regardless of its type } public void PrintCircumference(IShape shape ) { Console.WriteLine( shape.circumference ); // again its not important what is your shape, you cant use this function to print its cicumference } } |
类是对象的模板。它本质上是一个蓝图。所以对于灯来说,有一个开关按钮。比如当你调用这个方法时,一个值被发送到某个控制器,这个控制器会打开和关闭它。你所要做的就是调用开/关的方法,然后Viola就可以了。
接口非常相似。这里可能没有实现开/关方法。实际上,您必须编写代码来打开和关闭灯,但您必须编写打开/关闭方法,否则它不能是该接口。假设有一种新型的灯光具有调光功能。界面允许您为不同类型的光实现这个新功能。所以它基本上告诉你,你必须做这些事情(开/关),它是一个灯,但我们不关心你如何实现它。接口的某些部分可以为您实现,但其他部分必须实现。
什么时候接口才有意义?一种情况,其中有许多对象在性质上非常相似,但在实现上略有不同。例如,假设您有许多类型的形状。每个都有一个区域。三角形的计算与圆形的计算不同。现在假设您有数百个需要构建的形状,您不会一直为每种类型的形状创建新的对象,您只需要实现接口。这使某人有能力用相似的方法创建形状,甚至自定义形状,但实现方式不同。