关于c#:这里使用什么,抽象类还是接口?

What to use here, abstract class or Interface?

本问题已经有最佳答案,请猛点这里访问。

我有一个抽象类,称为ctest,它只包含抽象方法f1(),而不包含其他任何内容。类似地,我有一个接口itest,它只有一个方法f1()。这里CTEST抽象类和ITEST接口都执行相同的操作。

一个区别是,接口提供了灵活性,可以在已经从其他类派生但抽象类不能的任何类中实现。

除了上述区别之外,这两者的实际区别是什么?哪一个在这里有效(CTEST或ITEST)?什么时候该用什么?OO设计中的任何特定场景和对此的任何一般性建议都是有用的


除了继承,它还取决于场景。用一个很好的例子检查这个代码项目文章。

[来自文章]

Lets Assume you need to make three classes, first is CAR, second is
MAN, third is WOMAN. Now you need a function in each of them to define
how they Move. Now all three can move but CAR moves entirely in
different way than MAN and WOMAN. So here we use an Interface
IMOVEMENT and declare a function MOVE in it. Now all three classes can
inherit this interface. So the classes goes like this.

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
public interface IMovement
{
    void Move();
}

public class Car : IMovement
{
    public void Move()
    {
        //Provide Implementation
    }
}

public class Man : IMovement
{
    public void Move()
    {
        //Provide Implementation
    }
}

public class Woman : IMovement
{
    public void Move()
    {
        //Provide Implementation
    }
}

But, since MAN and WOMAN walk in similar way, so providing same
behavior in two different methods will be code redundancy, in simpler
words code is not re-used. So we can now define a Abstract Class for
Human Beings movements, so this class can be HUMANBEINGMOVEMENT. Also
the same can be applied to CAR class, since there are lot of
manufactures for cars and all cars move in similar way so we can also
define a abstract class for Cars movement which can be CARSMOVEMENT.
So our refactored code will be .

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
43
44
45
46
public interface IMovement
{
    void Move();
}

public abstract class CarsMovement : IMovement
{

    public virtual void Move()
    {
        //default behavior for cars movement
    }
}

public class SuzukiCar : CarsMovement
{
    public override void Move()
    {
        //Provide Implementation
    }
}

public abstract class HumanBeingMovement : IMovement
{

    public virtual void Move()
    {
        //default behavior for human being movement
    }
}

public class Man : HumanBeingMovement
{
    public override void Move()
    {
        //Provide Implementation
    }
}

public class Woman : HumanBeingMovement
{
    public override void Move()
    {
        //Provide Implementation
    }
}


Java中,InterfacesAbstract Classes更受欢迎。在有效Java中引用项目18

enter image description here

要点:

  • 可以对现有类进行追溯以实现新的接口。

  • 接口是定义mixin的理想选择。

  • 接口允许构造非体系结构类型的框架。

  • 接口支持安全、强大的功能增强。


优势:

抽象类的实现比接口好,因为抽象类的方法查找比接口快。如果修改接口,则必须更新实现类,但对抽象类的任何修改都不会对实现类产生影响。

缺点:

1
2
If you want to implement more than one parent class method , it is not possible.
But regarding to interface you can implement more than one.

在您提到的场景中,只有一个方法没有定义,最好的方法是接口。

接口在爪哇中提供的主要优点是可以实现多个接口,但只能扩展一个类。因此,如果您已经在扩展一个抽象类,那么就不需要选择扩展任何其他类。

Golden rule: Interface is better than abstract class if we only need
to define methods and not declare them.

既然说在您的情况下接口更好,程序员也应该从未来的角度考虑他的代码。你觉得你正在创建的类/接口将来会有更多的方法吗?您要定义这些方法还是只声明?对这些问题的回答将让您知道接口是否足够或是否需要抽象类。


在这种情况下没有区别,但是CTest类只有一个可以作为类继承的类。但是,ITest接口可以同时被其他类和接口继承。


在这种情况下,假设抽象类只包含抽象方法,在我看来,您应该使用接口。具有抽象方法和接口的抽象类具有相同的用途,但是,您只能扩展一个类,但可以根据需要实现任意多个类,因此,如果您决定从其他类继承某些功能,代码就不太容易发生重大更改。

关于你的问题:但是这两者的实际区别是什么?哪一个在这里有效(CTEST或ITEST)?什么时候该用什么?OO设计中的任何特定场景和对此的任何一般性建议都是有用的

接口类似于契约,当类实现接口时,它保证实现。当有人想要提供功能,但不想公开内部代码时,这通常很有用,因此开发人员只需抛出接口,这样您就可以在不知道每个方法是如何实现的情况下进行调用。显然,您可以实现任意多的接口。

抽象类允许您创建一个类,该类具有指定的某些行为,还有一些行为将在将来实现。但是,与接口不同,每个类只能扩展一个类,因此从这个角度来看,应该谨慎地扩展类。抽象类还允许您将行为注入到一个类中,并使其自动通过其子类传播。这通常使开发/维护的某些部分更加容易。


对我来说,最好在这里使用接口。当您可以在那里提取一些代码(您可以实现方法或者有其他东西想要调用它)时,应该使用抽象类。


在C中,它只允许单级继承。因此,接口可以用于执行多个继承

以及更多详情:

http://www.dotnetfunda.com/forums/thread4085-difference-between-interface-and-abstract-class.aspx

Difference between Abstract class and Interface in C# .Net