C# c中不同类型实例化之间的差异#

C# c中不同类型实例化之间的差异#,c#,.net,C#,.net,我想知道这两个实例化之间的区别 interface ITest { int TotalMarks(int englishMarks, int mathematicsMarks); } class TestClass : ITest { public int TotalMarks(int engMarks, int mathMarks) { return engMarks + mathMarks; } } class Program {

我想知道这两个实例化之间的区别

interface ITest
{
    int TotalMarks(int englishMarks, int mathematicsMarks);
}

class TestClass : ITest
{
    public int TotalMarks(int engMarks, int mathMarks)
    {
        return engMarks + mathMarks;
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass c = new TestClass();
        Console.Write(c.TotalMarks(10, 20));
        Console.Write("\n");

        ITest c1 = new TestClass();
        Console.Write(c1.TotalMarks(21, 34));

        Console.ReadKey();
    }
}
  • TestClass c=newtestclass()
  • ITest c1=newtestclass()

    他们都按照预期工作并给出结果。这两者有何不同?何时使用哪一种


不同之处在于,在使用接口的第二个接口上,您只能访问该特定接口上的成员,而不是整个类。这允许您在实际类上实现几个不同的接口,而用户只能访问特定的“container”

此外,接口驱动设计在单元测试中很好,因为您可以简单地交换一个类和另一个类

假设您有另一个类也实现了您的接口。如果您在任何上下文中创建的方法希望您将实际类作为参数,那么您现在必须更改该方法的签名,以便还允许第二个类的实例。如果该方法是为接口设计的,那么您可以将-
TestClass
另一个TestClass
实例传递给它,而不必考虑它的实际类型。这减少了类耦合,因为您不再依赖于实际的类,而只依赖于接口定义的成员。这些成员的实现方式对您的代码没有任何意义

铸造时也要小心。虽然可以说,
TestClass
的每个实例也实现了
ITest
,但并非所有
ITest
的实例都属于
TestClass
类型。因此,以下内容在运行时生成一个
InvalidCastException

ITest t = new TesClass();
AnotherTestClass t2 = (AnotherTestClass) t;

总而言之,接口只说明该接口的实例可以做什么,而不说明它是如何做到的,因为这对于任何消费代码来说都不重要。继续你的例子:你的
程序
不需要知道如何实际实现
TotalMarks
,只要它知道方法实际存在并返回它应该返回的内容。实施细节与
程序
无关。这就是所谓的有损类耦合。

可能有很多不同之处,但我要提到的主要方面很少

ITest c1 = new TestClass();
使用此接口创建对象允许创建实现类似ITest的TestClass的任何类的对象

class AnotherTestClass : ITest
{
    public int TotalMarks(int engMarks, int mathMarks)
    {
        return engMarks + mathMarks;
    }
}

 ITest c1 = new AnotherTestClass();
另一方面,在
TestClass
中声明一些新方法,并尝试使用通过接口创建的
c1
访问它。您将无法访问它,但如果您通过类而不是下面所示的接口在第一个方法中通过类创建,则可以访问新方法

class TestClass : ITest
{
    public int TotalMarks(int engMarks, int mathMarks)
    {
        return engMarks + mathMarks;
    }
    public void AdditionalMethod()
    {

    }
}

TestClass c = new TestClass();
c.AdditionalMethod(); //Valid
ITest c1 = new TestClass();
c1.AdditionalMethod(); //Invalid, compilation error

接口帮助我们创建松散耦合的应用程序。通过对模式进行操作,您可以阅读更多关于它的信息。

总而言之,接口还允许使您的代码更加灵活,一个类将依赖于一个接口而不是另一个类(尽管接口是类)。因此,如果您有一个模块需要一个IMoving对象,它可以接收Cat或Dog并工作。明年,您将为car编写一个程序,并且只要您的car类实现IMoving,您的模块也将为car工作。@fafase如果这是您的意思,请参阅我答案的第三段。感谢您如此简洁地解释它,我开始了解借助接口的松散耦合类的概念。我对接口还有另一个疑问。ITest t=新的ITest();抛出编译器错误。是的,这是有意义的,因为接口并没有方法的定义,它不能自己做任何事情。所以我们不能实例化它。但是当我们说ITest t=newtestclass()时,它为什么能够实例化(创建接口实例)它呢?接口中仍然没有任何方法的定义?我希望你明白我的问题。@HimBromBeere嗯,可能是的。假设我的猫、狗和车的上下文可能更具教育意义:)。它实例化是因为您使用了新的TestClass()。这是一个完全实现的对象类型。然后,该对象的地址被传递给一个类型为ITest的变量,这个人只能访问ITest知道的内容。t指向TestClass对象,但t只看到它的最部分。如果您强制转换到一个TestClass,TestClass tc=(TestClass)t;它将起作用,tc现在可以看到整个TestClass对象。您没有实例化ITest对象,无法实例化接口,因为它们没有完全实现。感谢您的回答。。。我正在浏览参考链接。