只需5分钟的概述就可以了....
答案 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)
答案 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
在这种情况下:get
和size
是开发人员需要实现的抽象方法。其余功能可能已经实现。
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();
}
}
}