请解释C#中抽象方法的实用性

时间:2010-05-20 18:02:26

标签: c# .net

只需5分钟的概述就可以了....

11 个答案:

答案 0 :(得分:10)

public abstract class MyBaseController {
    public void Authenticate() { var r = GetRepository(); }
    public abstract void GetRepository();
}
public class ApplicationSpecificController {
    public override void GetRepository() { /*get the specific repo here*/ }
}

这只是一些虚拟代码,代表了我有的一些真实世界代码(为简洁起见,这只是示例代码)

我有2个ASP MVC应用程序做了相当类似的事情。 安全性/会话逻辑(以及其他事物)在两者中都是相同的。 我已将两者的基本功能抽象为一个他们都继承的新库。当基类需要只能从实际实现中获取的东西时,我将它们实现为抽象方法。因此,在上面的示例中,我需要从数据库中提取用户信息以在基本库中执行身份验证。为了获得应用程序的正确数据库,我有一个抽象的GetRepository方法,它返回应用程序的存储库。从这里开始,基地可以在repo上调用一些方法来获取用户信息并继续进行验证,或者其他任何方法。

当需要对身份验证进行更改时,我现在只需要更新一个lib而不是在两者中重复工作。所以简而言之,如果你想要实现一些功能但不是全部,那么抽象类的效果很好。如果您不想实现任何功能,请使用界面。

答案 1 :(得分:9)

只需查看Template Method Pattern

答案 2 :(得分:7)

public abstract class Request
{
   // each request has its own approval algorithm. Each has to implement this method
   public abstract void Approve();

   // refuse algorithm is common for all requests
   public void Refuse() { }

   // static helper
   public static void CheckDelete(string status) { }     

   // common property. Used as a comment for any operation against a request
   public string Description { get; set; }

   // hard-coded dictionary of css classes for server-side markup decoration
   public static IDictionary<string, string> CssStatusDictionary
}

public class RequestIn : Request
{
   public override void Approve() { }
}

public class RequestOut : Request
{
   public override void Approve() { }
}

答案 3 :(得分:1)

使用Template Method Pattern时,使用抽象方法非常常见。您可以使用它来定义算法的骨架,并让子类修改或改进算法的某些步骤,而无需修改其结构。

查看doFactory's Template Method Pattern page中的“真实世界”示例。

答案 4 :(得分:1)

.NET Stream类就是一个很好的例子。 Stream类包括所有流实现的基本功能,然后特定的流为与I / O的实际交互提供特定的实现。

答案 5 :(得分:1)

基本思想是使抽象类提供框架和基本功能,并让具体实现提供所需的确切细节。

假设您有一个带有+20方法的接口,例如List接口。

List {interface }
    + add( object: Object )
    + add( index:Int, object: Object )
    + contains( object: Object ): Bool
    + get( index : Int ): Object
    + size() : Int 
    ....

如果有人需要为该列表提供实现,则必须每次都实现+20方法。

另一种方法是拥有一个实现大多数方法的抽象类,并让开发人员实现其中的一些。

例如

  

要实现不可修改的列表,程序员只需要扩展此类并提供get(int index)和size()方法的实现

AbstractList: List
    + get( index: Int ) : Object { abstract }
    + size() : Int { abstract }
    ... rest of the methods already implemented by abstract list

在这种情况下:getsize是开发人员需要实现的抽象方法。其余功能可能已经实现。

EmptyList: AbstractList 
{
     public overrride Object Get( int index ) 
     {
          return this;
     }
     public override int Size() 
     {
          return 0;
     }
}

虽然这种实现可能看起来很荒谬,但初始化变量会很有用:

  List list = new EmptyList();

   foreach( Object o: in list ) {
   }

避免空指针。

答案 6 :(得分:0)

用于自制的俄罗斯方块,其中每种类型的Tetraminos都是四氨基类的儿童类。

答案 7 :(得分:0)

每当你有一个实际包含某些实现代码的基类时,你可以使用抽象方法(而不是接口),但是对于它的一个或多个方法没有合理的默认实现:

public class ConnectionFactoryBase {

    // This is an actual implementation that's shared by subclasses,
    // which is why we don't want an interface
    public string ConnectionString { get; set; }

    // Subclasses will provide database-specific implementations,
    // but there's nothing the base class can provide
    public abstract IDbConnection GetConnection() {}

}

public class SqlConnectionFactory {
    public override IDbConnection GetConnection() {
        return new SqlConnection(this.ConnectionString);
    }
}

答案 8 :(得分:0)

例如,假设您有一些与数据库中的行对应的类。您可能希望在ID相等时将这些类视为相等,因为这就是数据库的工作方式。因此,您可以将ID设置为抽象,因为这样可以编写使用该ID的代码,但在您了解具体类中的ID之前不会实现它。这样,您就可以避免在所有实体类中实现相同的equals方法。

public abstract class AbstractEntity<TId>
{
    public abstract TId Id { get; }

    public override void Equals(object other) 
    {
         if (ReferenceEquals(other,null)) 
             return false;
         if (other.GetType() != GetType() ) 
             return false;
         var otherEntity = (AbstractEntity<TId>)other;
         return Id.Equals(otherEntity.Id);
    } 
}

答案 9 :(得分:0)

我不是C#家伙。介意我使用Java吗?原理是一样的。我在游戏中使用了这个概念。我非常不同地计算不同怪物的护甲值。我想我可以让他们跟踪各种常数,但这在概念上要容易得多。

abstract class Monster {
    int armorValue();
}

public class Goblin extends Monster {
    int armorValue() { 
        return this.level*10;
    }
}

public class Golem extends Monster {
    int armorValue() {
        return this.level*this.level*20 + enraged ? 100 : 50;
    }
}

答案 10 :(得分:0)

一个例子

namespace My.Web.UI  
{  
    public abstract class CustomControl : CompositeControl  
    {
        // ...

        public abstract void Initialize();

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            // Anything custom

            this.Initialize();
        }
    }
}