C# 构造函数中的抽象类型而不是具体类型
我有一个对象,假设它是数据,在 他们称之为web方法C# 构造函数中的抽象类型而不是具体类型,c#,.net,polymorphism,abstract-class,C#,.net,Polymorphism,Abstract Class,我有一个对象,假设它是数据,在 他们称之为web方法 // NewData1.cs public NewData1(Concrete1 con) { ID = con.ID; var results= con.listOfResults(); var something= con.GetSomething(); Something =
// NewData1.cs
public NewData1(Concrete1 con)
{
ID = con.ID;
var results= con.listOfResults();
var something= con.GetSomething();
Something = new List<Somethings>();
con.DoSomething();
}
// NewData2.cs
public NewData2(Concrete2 con)
{
ID = con.ID;
var results= con.listOfResults();
var something= con.GetSomething();
Something = new List<Somethings>();
con.DoSomething();
}
// NewData3.cs
public NewData3(Concrete3 con)
{
ID = con.ID;
var results= con.listOfResults();
var something= con.GetSomething();
Something = new List<Somethings>();
con.DoSomething();
}
//NewData1.cs
公共新数据1(混凝土1 con)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
//NewData2.cs
公共新数据2(混凝土2 con)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
//NewData3.cs
公共新数据3(混凝土3 con)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
正如您所看到的,这些类做同样的事情(它不是我的代码..我想更改它)。
唯一不同的是具体类型(1,2,3),它们在调用方法时执行不同的逻辑
您知道如何将这些类简化为一个类,但仍然使它们各自具有其特殊的逻辑而不相同吗?您想要一个抽象基类:
public abstract class BaseClass
{
// Use protected fields to store data that only this class and derived
// classes can access.
protected List<Something> storedSomethings;
//Define an abstract method signature for methods that the concrete classes
// have very different implementations for:
public abstract List<Something>GetSomethings();
//Use a virtual method for methods that are identical or similar on
//the concrete classes:
public virtual void AddSomethings(List<Something> addList)
{
storedSomethings.Add(addList);
}
}
创建以下基类
public class Concrete
{
public int ID { get; set; }
public virtual something GetSomething()
{
}
public virtual void DoSomething()
{
}
}
让你的concrete1、concrete2等课程扩展到Concrete。如果需要,这些类将能够重写GetSomething方法。
那你只需要一个
public NewData2(Concrete con)
{
ID = con.ID;
var results= con.listOfResults();
var something= con.GetSomething();
Something = new List<Somethings>();
con.DoSomething();
}
public NewData2(混凝土施工)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
如果您的Concrete1
、Concrete2
和Concrete3
类共享相同的方法,您可以将其提取到接口中,并使其实现:
// an interface is simply a contract
interface ICanGetSomething
{
int ID { get; }
List<Result> ListOfResults();
Something GetSomething();
}
// your concrete classes should all implement the same interface
class Concrete1 : ICanGetSomething { ... }
class Concrete2 : ICanGetSomething { ... }
class Concrete3 : ICanGetSomething { ... }
如果它们也共享相同的功能,则还可以使用公共抽象类重用所有公共代码:
abstract class Base : ICanGetSomething { ... }
// your concrete classes should all inherit from the same base class
class Concrete1 : Base { ... }
class Concrete2 : Base { ... }
class Concrete3 : Base { ... }
无论哪种方式,我都建议使用接口来定义合同。由于C#不支持多重继承,因此您不希望强制所有具体实现都从单个基类派生(除非有必要)。这仍然意味着您将在有共享功能的地方使用继承,但是您的
NewData
方法应该接受参数的接口,而不是基类。如果所有3个派生类都具有完全相同的签名,您可以从具体类创建一个抽象基类
public class Concrete
{
public int ID { get; set; }
public virtual something GetSomething()
{
}
public virtual void DoSomething()
{
}
}
基类:
public abstract class AbstractBaseClass
{
public long ID { get; set; }
public abstract List<string> ListOfResults();
public abstract string GetSomething();
public abstract void DoSomething();
}
public void NewData(AbstractBaseClass abs)
{
ID = abs.ID;
var results= abs.listOfResults();
var something= abs.GetSomething();
abs.DoSomething();
}
您现在可以执行以下操作,例如:
NewData data = new NewData(new Concrete1());
NewData构造函数中的所有调用都将定向到Concrete1子类
如果您只能有一个NewData实例,则可以在需要时使用来更改具体类。不能使用不同类型的参数,除非它们也继承了一个公共基类,或者您可以通过某种方式使其与泛型方法(通常还需要一个公共基类或委托进行转换)一起使用。Peter,如果调用baseClass.GetSomthing,它如何知道要调用什么GetSomthing?Concrete1?Concrete2?Conret3?它将调用您拥有的对象上的方法。因此,如果您将Concrete2传递给newdata,它将对传入的Concrete2实例执行所有操作代码>。这意味着类的静态方法。也许您应该更改您的示例,以反映您的意思是对class@Kazuo:是的,修复最后一个代码段以使其真正编译将是一个好主意。@DevTraveler:Google表示“vtable”或“dynamic dispatch”。对虚拟方法(通常)是如何在引擎盖下工作的有一个很好的解释。注意:首先,基类通常被命名为
base
或其他什么<代码>具体意味着它是抽象的“有用”实现。如果基类不包含抽象方法,则它不必是抽象的。Tbh我更喜欢你的答案是使用我在给出答案后想到的界面。但是现在已经完成了,没有必要改变它来匹配已经存在的答案。我会编辑我的,并把它留在这里,以防有人能从中得到任何用处。
public abstract class AbstractBaseClass
{
public long ID { get; set; }
public abstract List<string> ListOfResults();
public abstract string GetSomething();
public abstract void DoSomething();
}
public class Concrete1 : AbstractBaseClass
{
public override List<string> ListOfResults()
{
// Logic
}
public override string GetSomething()
{
// Logic
}
public override void DoSomething()
{
// Logic
}
}
public void NewData(AbstractBaseClass abs)
{
ID = abs.ID;
var results= abs.listOfResults();
var something= abs.GetSomething();
abs.DoSomething();
}
NewData data = new NewData(new Concrete1());