接口和抽象类在解耦方面的区别?

Pan*_*kaj 17 c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-2

我们知道Interface和Abstract类之间基本上有两个重要的区别.

  1. 我们可以在抽象类中使用函数定义.当我们想要在类中添加函数而不需要追踪它的所有实现时,这是有利的.

  2. 我们可以有多个接口实现.

我刚才知道我们可以在解耦方面区分它们吗?

你的评论...

另外,如果您能提供一个非常基本的链接来解释接口和抽象类的解耦?

我们通常使用业务逻辑层,数据访问层(包含抽象函数)和DataAccess.SqlServer层.对?尽管我们知道业务需求,但为什么我们要创建数据访问层(包含抽象函数),为什么业务逻辑层不能直接访问DataAccess.SqlServer层

Tra*_*s J 20

解耦

在编程和设计中,这通常是使代码可以在尽可能少的依赖性下重复使用的行为.

在这种情况下的工厂模式

使用工厂模式时,您有一个集中式工厂,可以创建对象而无需自己定义它们.这取决于对象的定义.

摘要和界面

接口

定义接口是最佳实践,因为它允许使用轻量级类型进行推理,并且还提供所有继承类必须遵守的蓝图.例如,IDisposable必须实现该Dispose方法.请注意,这与接口分离,因为每个继承的类IDisposable都将定义自己的Dispose方法函数.

抽象

Abstract类似于接口,因为它用于继承和推理,但它包含所有类将继承的定义.每辆汽车都会有一个引擎,所以汽车的一个好的抽象类可以包括一套预定义的引擎方法.

编辑

说明

在这里,您将看到一个使用接口和抽象类的继承的简单示例.当接口由抽象类继承然后定制它的方法时,就会发生解耦.这允许类继承抽象类,并且仍然具有与接口相同的类型.优点是当期望的类型是原始接口时,可以使用继承抽象类的类.

解耦

该优点允许使用符合预期接口的任何实现.因此,可以编写和传入许多不同的重载.这是一个例子.

接口定义

public interface IReady
{
    bool ComputeReadiness();
}
Run Code Online (Sandbox Code Playgroud)

遗产

public abstract class WidgetExample : IReady
{
    public int WidgetCount { get; set; }
    public int WidgetTarget { get; set; }
    public bool WidgetsReady { get; set; }

    public WidgetExample()
    {
        WidgetCount = 3;
        WidgetTarget = 45;
    }

    public bool ComputeReadiness()
    {
        if (WidgetCount < WidgetTarget)
        {
            WidgetsReady = false;
        }
        return WidgetsReady;
    }
}


public class Foo : WidgetExample
{
    public Foo()
    {
        this.WidgetTarget = 2;
    }
}

public class Bar : IReady
{
    public bool ComputeReadiness()
    {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

解耦

public class UsesIReady
{
    public bool Start { get; set; }
    public List<string> WidgetNames { get; set; }

    //Here is the decoupling. Note that any object passed
    //in with type IReady will be accepted in this method
    public void BeginWork(IReady readiness)
    {
        if (readiness.ComputeReadiness())
        {
            Start = true;
            Work();
        }
    }

    private void Work()
    {
        foreach( var name in WidgetNames )
        {
            //todo: build name
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

多态性

public class Main
{
    public Main()
    {
        //Notice that either one of these implementations 
        //is accepted by BeginWork

        //Foo uses the abstract class
        IReady example = new Foo();
        UsesIReady workExample = new UsesIReady();
        workExample.BeginWork(example);

        //Bar uses the interface
        IReady sample = new Bar();
        UsesIReady workSample = new UsesIReady();
        workSample.BeginWork(sample);
    }
}
Run Code Online (Sandbox Code Playgroud)


maj*_*ann 6

我一直在寻找答案,这些问题似乎都有些复杂.所以这是我(希望)更简单的答案.

  • 没有任何实现细节可用于当前代码范围时,应使用接口.
  • 摘要时,应使用一些执行细节提供给您
  • 而且,为了完整性,当所有实现细节都可用时,您应该使用.

在解耦方面,虽然我有点同意Shelakel,为了这个问题的目的,并说明完全脱钩的设计实践,我建议如下:

  • 始终使用接口来定义外部行为.
  • 当您有一些可用的实现细节时,使用 抽象类来定义它们,但是在抽象类上实现接口,并依次从这些类继承.

这确保了以后如果您需要在新实现中更改一些模糊的实现细节,您可以在不修改现有抽象类的情况下执行此操作,并且还能够将不同的实现类型分组到不同的抽象类中.

编辑:我忘了包含链接:) http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface