如果我必须在其他地方实现所有成员,那么接口的用途是什么?

时间:2014-01-21 06:09:39

标签: c# interface

我可以在接口中声明函数和属性,但我无法实现它们。当我从界面继承时,我现在必须在我的班级中实现所有这些成员。如果我必须这样做,那么声明界面的重点是什么?

例如,这是一个示例界面:

namespace InterfaceExample
{
    public interface IVehicle
    {
        int Doors { get; set; }
        int Wheels { get; set; }
        Color VehicleColor { get; set; }
        int TopSpeed { get; set; }
        int Cylinders { get; set; }
        int CurrentSpeed { get; }

        string DisplayTopSpeed();
        void Accelerate(int step);
    }
}

我已在此界面中声明了所有属性和功能。现在,当我在我的班级中使用这个界面时:

namespace InterfaceExample
{
    public class Motorcycle : IVehicle
    {
        private int _currentSpeed = 0;

        public int Doors { get; set; }

        public int Wheels { get; set; }

        public Color VehicleColor { get; set; }

        public int TopSpeed { get; set; }

        public int HorsePower { get; set; }

        public int Cylinders { get; set; }

        public int CurrentSpeed
        {
            get { return _currentSpeed; }
        }


        public Motorcycle(int doors, int wheels, Color color, int topSpeed, int horsePower, int cylinders, int currentSpeed)
        {
            this.Doors = doors;
            this.Wheels = wheels;
            this.VehicleColor = color;
            this.TopSpeed = topSpeed;
            this.HorsePower = horsePower;
            this.Cylinders = cylinders;
            this._currentSpeed = currentSpeed;
        }

        public string DisplayTopSpeed()
        {
            return "Top speed is: " + this.TopSpeed;
        }

        public void Accelerate(int step)
        {
            this._currentSpeed += step;
        }
    }

我必须再次声明所有属性。

那么为什么首先要使用界面呢?这似乎是浪费时间,因为无论如何我将在班上实施所有成员。

6 个答案:

答案 0 :(得分:7)

正如其他答案强调interfaces告诉您what to dohow to do由您来实施。

1。那么为什么我浪费时间创建一个接口如果我必须在我的班级中声明My Interface的所有属性和功能。

确定。您正在创建Motorcycle并通过实施IVehicleMotorCycle接口is forced to implement all the members of the interface IVehicle

如果您没有使用名为IVehicle的界面,实际上forget implement something可能已经实施了Car

明天,如果有人想要构建IVehicle,那么您可以从IVehicle interface实施,人们可以实现其所有方法并进行自定义。

whenever you build a vehicle class, it reminds and forces you to make sure that you rightly build a vehicle的目的是确保 integer

<强> 2。对于属性,界面是浪费时间吗?

不,绝对不是。

例如,每当您想要返回车速时,而不是仅仅将车速四舍五入到您想要的floating point,{/ 1}},

10 // public float currentSpeed { get; set; }

10.5 // public float currentSpeed { get {return {//write custom logic}; set; }
该物业的

Notice the customisation in Get accessor

第3。什么时候应该使用抽象类?

all derived class would be using some repeated method时应使用抽象类。例如,

public abstract Class AbstractClass
{
        public virtual int Doors { get; set; }

        public virtual int Wheels { get; set; }

        public virtual Color VehicleColor { get; set; }

        public virtual int TopSpeed { get; set; }

        public virtual int HorsePower { get; set; }

        public virtual int Cylinders { get; set; }

        public string WhatSideDriving
        {
           if (Country == "US") return "Keep Right";
           if (Country == "India") return "Keep Left";
        }

}

请注意,方法WhatSideDrivingalready implemented,并且可以由派生自此类的所有类使用。但是,根据所需的功能,可以覆盖其他成员,并且可以implemented

答案 1 :(得分:6)

  

那么为什么我浪费时间创建一个接口如果我必须在我的类中声明My Interface的所有属性和功能。

因为界面就是这样; a(公共)接口。它没有定义实现,只定义用于与其任何实现接口的方法和属性。

当然,所述接口的实现者必须定义它的实现。你还有什么期望这个呢?

也就是说,属性可以隐式(并且不可见)地实现为自动属性并不是不可思议,但这对于方法不起作用,并且您通常需要超过get; set;,因此它几乎不会提供好处(即,不值得努力的功能)。

答案 2 :(得分:3)

严格来说,声明接口浪费时间。您可以跳过界面并节省一些时间。

然而,你会切入错误的角落。虽然这是一些额外的时间和工作,但从长远来看,接口是非常宝贵的。真正优秀的软件工程师的一个标志是能够很好地设计接口。

为了不那么抽象,界面的设计正是为了这个目的:形式化两种类之间的接口(换句话说,两个类如何一起工作)。这有点像课程之间的契约,每个班级都说明了他们承诺提供的内容以及他们期望的内容。例如,您的IVehicle示例发誓,它将始终具有名为doors的属性。然后,与IVehicle一起使用的任何代码都可以信任IVehicle的所有实现始终拥有Doors。您现在可以安全地编写访问IVehicle.Doors的代码,因为无论将哪种特定实现传递给此方法,您的代码肯定会有效 - 即使Vehicles软件包开发人员决定有一天添加一些你从未听说过或想过的车辆!

如果只有一个实现该接口的小类,并且您是唯一的开发人员,那么接口可能是多余的。但是,如果有多种车辆,每种车辆都有自己的逻辑和不同的成员,那么一些通用代码必须使用它们呢?例如,车辆跟踪经理必须处理班级CarTruckPlane等。为什么不?他们都有速度和位置,这就是最重要的。

此外,当您让其他开发人员编写自己的车辆时,界面是一种很好的方式,可以向他们展示如何使用它来处理其余的代码。

同样,当你处理一个大型项目,并在不同的开发人员之间拆分每个部分时,精心设计的接口可以确保这些程序员在相对隔离的项目的不同部分工作,仍然会创建一个完整的工作,谢谢适合放在一起的部分。

同样,一个好的界面是一个很好的方式来开始一个复杂的类,即使你自己编码:它将帮助你跟踪你需要实现什么和如何,但不像一个更熟悉的技术规范,一个接口可以编译器可以理解它,以便它可以在很多方面为您提供帮助(例如,当您希望使用类的部分编写逻辑时,可以使用IntelliSense的帮助稍后将实现)。

特别是在C#中,界面也有实际的好处。您不能从C#中的多个类或抽象类继承(与C ++不同)。这样做是因为多重继承有时会使程序员的生活变得非常困难。但是你可以从多个接口继承,并且因为它们只是接口(没有实现),所以“多重继承”的问题就不那么重要了。

最后,一个真实世界的例子:Microsoft为您提供了一个List.Sort方法,它将有助于对任何对象的列表进行排序。对于像数字和字符串这样的事情来说,显然很容易做到这一点,但是可以让它对你制作的任意对象进行排序,比如车辆。但是,微软怎么可能知道你将实现什么类的类,以及你打算如何对它们进行排序?他们没有,但他们为您提供了一个名为IComparable的界面。这定义了排序代码需要调用的方法,以便能够比较两个对象进行排序。如果您放入列表中的对象实现了此IComparable,您将告诉Microsoft的List.Sort代码如何对对象进行排序,现在您不再需要编写自己的排序函数,因为您可以使用精心设计,测试,记录和调试的Microsoft。

作为练习,请尝试编写一个程序,其中包含Triangle个类列表(仅包含abc个字段,用于存储每个类的长度侧面和CalculateArea方法),然后使用Microsoft的List.Sort按区域对其进行排序。不要编写自己的排序代码,也不要使用LINQ OrderBy之类的东西,而是通过Triangle实现IComparable来实现。然后想一想:如果你是负责开发所有.NET库的项目经理,你会如何写一个任何人都可以使用的排序函数,即使是他们自己的奇怪类?

答案 3 :(得分:0)

接口是定义,而不是实现。类是实现和定义。

接口的意思是将实现与定义分开,以便使用者不了解用于实现接口的实际对象。

是的,这是更多的工作,但好的设计总是比工作更糟糕。

答案 4 :(得分:0)

如果需要创建界面,可以创建界面。

您可以将所有类型的车辆作为接口类型传递给方法。如果您声明以下所有三项并且您需要计算它们的燃油效率,那么您需要三种不同的方法来做到这一点。

示例:

public class Truck {}

public class Car {}

public class Motorcycle {}

使用界面,您需要一种方法:

public int GetFuelEfficiency(IVehicle vehicle)

接口要求您或其他任何实现它的人声明其所有属性和方法。这样,实现接口的所有类都将包含其他代码以相同方式处理的所有必需属性和方法,而不管特定于类的实现。

还有其他原因可以在C#中声明缺少多重继承等界面。

答案 5 :(得分:0)

Interface提供了实施蓝图。您可以自由地从该蓝图创建实际的类。为此,您必须定义该蓝图的所有方面。

接口主要用于创建应用程序的可插拔接口,也用于支持多重继承。

参考文献:

如果符合您的目的,您也可以使用抽象类。但抽象类!=接口。