C# 如何使用界面和浇铸的目的?

C# 如何使用界面和浇铸的目的?,c#,C#,我在这两种情况下都使用了接口。这是我的第一个案例使用界面吗?? 这是我的接口和类 interface IAddition { int Add(); } interface IMultiplication { int Multiplication(); } 这是我的课 public class Calculation : IAddition, IMultiplication { int x, y; public Calculation(int x, int y)

我在这两种情况下都使用了接口。这是我的第一个案例使用界面吗?? 这是我的接口和类

interface IAddition {
    int Add();
}

interface IMultiplication {
    int Multiplication();
}
这是我的课

public class Calculation : IAddition, IMultiplication {
    int x, y;
    public Calculation(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int Add() {
        return (x + y);
    }
    public int Multiplication() {
        return (x * y);
    }
} 
第一种情况是这样的吗

class Program {
    static void Main(string[] args) {
        Calculation cal = new Calculation(20, 30);
        Console.WriteLine("Sum is= " + cal.Add());
        Console.WriteLine("Multiplication is= " + cal.Multiplication());
        Console.ReadKey();
    }
}
class Program {
    static void Main(string[] args) {
        Calculation cal = new Calculation(20, 30);
        IAddition add = (IAddition)cal;
        IMultiplication mul = (IMultiplication)cal;
        Console.WriteLine("Sum is= " + add.Add());
        Console.WriteLine("Multiplication is= " + mul.Multiplication());
        Console.ReadKey();
    }
}
第二种情况是这样的

class Program {
    static void Main(string[] args) {
        Calculation cal = new Calculation(20, 30);
        Console.WriteLine("Sum is= " + cal.Add());
        Console.WriteLine("Multiplication is= " + cal.Multiplication());
        Console.ReadKey();
    }
}
class Program {
    static void Main(string[] args) {
        Calculation cal = new Calculation(20, 30);
        IAddition add = (IAddition)cal;
        IMultiplication mul = (IMultiplication)cal;
        Console.WriteLine("Sum is= " + add.Add());
        Console.WriteLine("Multiplication is= " + mul.Multiplication());
        Console.ReadKey();
    }
}
这两条线的用途是什么???这里是什么目的铸造??虽然第一种情况下有相同的输出

IAddition add = (IAddition)cal;
IMultiplication mul = (IMultiplication)cal;

只有第二种情况编程到
iadition
immultiplication
接口。即使
计算
类没有实现
iadition
immultiplication
,第一种情况仍然有效

铸造的目的是什么

请注意,由于您使用显式接口类型声明变量,因此可以在
mul
add
的声明中安全地删除强制转换:

IAddition add = cal;
IMultiplication mul = cal;
您还可以使用隐式类型声明重写声明:

var add = (IAddition)cal;
var mul = (IMultiplication)cal;
这两条线的用途是什么


这些行使用
Calculation
实现的接口类型声明两个变量。在本例中,它们没有实际区别,但通常可以使用
add
mul
来具体说明编程的抽象级别。例如,
IAddition add
告诉程序的读者,除了与添加相关的方面外,您不需要使用
cal
的任何方面。

只有第二种情况的程序才能使用
IAddition
immultiplication
接口。即使
计算
类没有实现
iadition
immultiplication
,第一种情况仍然有效

铸造的目的是什么

请注意,由于您使用显式接口类型声明变量,因此可以在
mul
add
的声明中安全地删除强制转换:

IAddition add = cal;
IMultiplication mul = cal;
您还可以使用隐式类型声明重写声明:

var add = (IAddition)cal;
var mul = (IMultiplication)cal;
这两条线的用途是什么


这些行使用
Calculation
实现的接口类型声明两个变量。在本例中,它们没有实际区别,但通常可以使用
add
mul
来具体说明编程的抽象级别。例如,
iadition add
告诉程序的读者,除了与添加相关的内容外,您不需要使用
cal
的任何方面。

这都是为了隐藏复杂性。当你做这个演员时

     IAddition add = (IAddition)cal;
然后,您可以处理此
add
项,就好像它所能做的就是实现您的
iadition
界面一样。如果您正在实现一个复杂的系统,那么这可能会很方便


例如,您可以定义一个
IGetNextItem
接口。然后,您可以选择在一个类中实现该接口,该类从DBMS获取一个项,另一个类生成一个随机伪项。您可以强制转换任意一个对象,然后将其传递给消费这些项目的软件,而无需告诉消费软件获取项目的实际工作方式。

这都是为了隐藏复杂性。当你做这个演员时

     IAddition add = (IAddition)cal;
然后,您可以处理此
add
项,就好像它所能做的就是实现您的
iadition
界面一样。如果您正在实现一个复杂的系统,那么这可能会很方便


例如,您可以定义一个
IGetNextItem
接口。然后,您可以选择在一个类中实现该接口,该类从DBMS获取一个项,另一个类生成一个随机伪项。您可以强制转换任意一个对象,然后将其传递给消费这些项目的软件,而无需告诉消费软件获取项目的实际工作方式。

您不需要强制转换。你可以说

IAddition add = cal;

但是,关键是您正在创建一个实现IAdition接口的任何类型的对象

你不需要演员阵容。你可以说

IAddition add = cal;

但是,关键是您正在创建一个实现IAdition接口的任何类型的对象

其他答案涵盖了给定的示例代码,但值得补充的是,对于显式接口实现,规则是不同的

例如,如果示例类按如下方式实现:

public class Calculation : IAddition, IMultiplication {
    int x, y;
    public Calculation(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int IAddition.Add() {
        return (x + y);
    }
    public int IMultiplication.Multiplication() {
        return (x * y);
    }
} 
那就需要演员阵容了。例如:

Calculation cal = new Calculation(10, 10);
cal.Multiplication(); // this will cause a compiler error
((IMultiplication)cal).Multiplication(); // This is the required way to do it

有关更多信息,其他答案包括给定的示例代码,但值得补充的是,对于显式接口实现,规则是不同的

例如,如果示例类按如下方式实现:

public class Calculation : IAddition, IMultiplication {
    int x, y;
    public Calculation(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int IAddition.Add() {
        return (x + y);
    }
    public int IMultiplication.Multiplication() {
        return (x * y);
    }
} 
那就需要演员阵容了。例如:

Calculation cal = new Calculation(10, 10);
cal.Multiplication(); // this will cause a compiler error
((IMultiplication)cal).Multiplication(); // This is the required way to do it

有关本例中的更多信息,目的只是向您展示如何转换类型。这对代码的工作方式没有影响,但是您可以看到,如果您尝试
add.Multiplication()
,编译器会告诉您这是不允许的

在这样一个简单的例子中,没有理由像这样强制转换和声明变量。然而,在更大的应用程序中,接口分离原则帮助我们避免不同代码片段之间的紧密耦合。例如,您可以编写如下方法:

int SumAll(IAddition adder, params int[] values)
{
    int sum = 0;
    foreach(int n in values)
    {
        sum = adder.Add(sum, values[i]);
    }
    return sum;
}
如果将
计算器
传递给上面的方法,则该方法可以正常工作,但它不必使用
计算器
。因为你知道你不需要在这个方法中乘以任何东西,这就把你的依赖性限制在你真正需要的东西上。将来,您可能会发现实现一个带有上限的
Add
方法很有用,例如,无论添加了多少内容,都不允许数字超过某个数字。将该
iadition
对象传递到
SumAll
将产生不同的效果,并且您不必创建不同的
SumAll
方法来满足此需求

Console.WriteLine(SumAll(new Calculator(), 1, 2)); // 3
Console.WriteLine(SumAll(new Calculator(), 1, 2, 3)); // 6
Console.WriteLine(SumAll(new AdderWithMax(4), 1, 2)); // 3
Console.WriteLine(SumAll(new AdderWithMax(4), 1, 2, 3)); // 4
一般
public void MethodNeedsToAdd(IAddition addCalculator)
{
  if (addCalculator != null)
  {
    addCalculator.Add();
  }
}

MethodNeedsToAdd(one);   // Valid
MethodNeedsToAdd(two);   // Invalid