c#中不同类型实例化的区别

时间:2016-02-24 06:48:21

标签: 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
{
    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 = new TestClass();
  • ITest c1 = new TestClass();

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

2 个答案:

答案 0 :(得分:7)

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

此外,界面驱动设计非常适合单元测试,因为您可以简单地将一个类交换为另一个类。

想象一下,你有另一个同样实现你的界面的类。如果您在任何上下文中创建的方法都希望您将实际的类作为参数,那么您现在必须更改该方法的签名,以便也允许您的第二个类的实例。如果该方法是针对接口而设计的,则可以将 - #include<iostream> #include<sstream> #include<stdlib.h> using namespace std; bool isNumber(string s) { char* p; strtol(s.c_str(), &p, 10); return *p == 0; } int getNumber(string s) { char* p; return strtol(s.c_str(), &p, 10); } void askUser() { string strInput; int nums[4]; int cnt; do { cnt = 0; cout << "Input 4 values: "; getline(cin, strInput, '\n'); stringstream ss(strInput); string s; while (getline(ss, s, ' ')) { if(isNumber(s)) { if(cnt < 4) { nums[cnt] = getNumber(s); } cnt++; } } if(cnt!=4) { cout<<"Invalid number of inputs!\n"; } } while(cnt!=4); int i; cout<<"The 4 numbers input by the user are: "; for(i = 0; i < 4; i++) { cout<<nums[i]<<" "; } cout<<endl; } TestClass - 实例传递给它,而无需关心它的实际类型。这减少了类耦合,因为您不再依赖于实际类,而只依赖于接口定义的成员。如何实现这些成员对您的消费代码没有任何意义。

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

InvalidCastException

总而言之,界面只能说 该界面的一个实例,但 它实现了这一点,因为这对任何消费代码都不重要。继续你的例子:你的ITest t = new TesClass(); AnotherTestClass t2 = (AnotherTestClass) t; 不需要知道Program实际上是如何实现的,只要它知道方法实际存在并返回它应该返回的内容。实现细节与TotalMarks无关。这就是所谓的失败类耦合。

答案 1 :(得分:3)

可能会有很多不同,但我提到的主要内容很少

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

接口通过对模式program to interface not an implementation采取行动帮助我们创建松散耦合的应用,您可以阅读更多相关信息herehere