这个问题与面向对象设计的概念有关。
在下面的示例代码(C#)中,我有一个抽象基类Feature
,它有两个子类:SubFeature1
和SubFeature2
。在我的主程序中,我想通过将相应的参数(类的名称作为字符串)提供给唯一方法instantiateFeature()
来实例化每个方法。
当我运行此代码时,我收到的错误基本上表明类型OOP_example.Feature
无法隐式转换为OOP_example.SubFeature1
,因为已经存在明确的转换。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OOP_example
{
class Program
{
static void Main(string[] args)
{
Organization myOrga = new Organization();
SubFeature1 subObj1 = myOrga.instantiateFeature("SubFeature1");
SubFeature2 subObj2 = myOrga.instantiateFeature("SubFeature2");
}
}
public class Organization
{
Feature obj;
public Feature instantiateFeature(string s)
{
if (s.Equals("SubFeature1"))
{
obj = new SubFeature1();
}
else if (s.Equals("SubFeature2"))
{
obj = new SubFeature2();
}
return obj;
}
}
public abstract class Feature
{
public abstract void doSomething();
}
public class SubFeature1 : Feature
{
private int[] _val1;
//constructor
public SubFeature1()
{
_val1 = new int[2];
_val1[0] = 1;
_val1[1] = 2;
}
//this is the only method that inherits from class Feature
public override void doSomething()
{
//not implemented yet
}
//this is some other class that does not inherit from Feature
public void doSomethingElse()
{
//not implemented yet
}
}
public class SubFeature2 : Feature
{
private int[] _val1;
//constructor
public SubFeature2()
{
_val1 = new int[2];
_val1[0] = 1;
_val1[1] = 2;
}
//this is the only method that inherits from class Feature
public override void doSomething()
{
//not implemented yet
}
//this is some other class that does not inherit from Feature
public void doSomethingElse()
{
//not implemented yet
}
}
}
我不想直接实例化每个子类,因为将来会有很多子类。我以为我可以使用继承的概念来构造我的代码,因为我的所有类中都存在一些方法(这里,doSomething()
)。
实现这一目标的常用方法是什么?谁能告诉我一个最佳实践?
谢谢!
答案 0 :(得分:3)
instantiateFeature
方法的返回类型为Feature
,因此如果您要将其分配给SubFeature1
,则需要投射:
SubFeature1 subObj1 = (SubFeature1)myOrga.instantiateFeature("SubFeature1");
SubFeature2 subObj2 = (SubFeature2)myOrga.instantiateFeature("SubFeature2");
但无论如何,如果你已经知道该方法将要返回的具体类型,那么使用工厂方法是没有意义的;你也可以直接实例化具体类。工厂方法的要点通常是从实际实现中抽象出调用代码:
Feature subObj1 = myOrga.instantiateFeature("SubFeature1");
Feature subObj2 = myOrga.instantiateFeature("SubFeature2");
作为旁注,在Organization
课程中,您应该将obj
声明为本地变量,而不是字段。将其设为字段意味着instantiateFeature
方法不是线程安全的。
答案 1 :(得分:0)
我认为你试图使用的概念不是真正的继承而是多态,你应该做的是创建一个具有Feature类型的对象并与一个新的Feature1 / 2相关联。当您在其中一个上使用方法时,它将首先搜索“执行”类型。
答案 2 :(得分:0)
instantiateFeature
返回Feature
,可以是SubFeature1
或SubFeature2
。如果你写SubFeature1 a = myOrga.instantiateFeature("SubFeature2");
怎么办?编译器无法确定,因此它会显示错误。这种抽象基类的目的是定义一些非常重要的部分,足以让你工作而不必担心你现在正在使用哪些子类。所以你要做的是设计这样的Feature
基类和编写代码,它只使用Feature
个变量。
编辑,文字太大而无法发表评论
让我向您展示一下我所谈论的一个小例子。想象一下,我们有子功能,其中一个订购披萨。现在我们有了子类:OrderPizzaByPhoneFeature,OrderPizzaByEmailFeature。他们两个doSomething
订单披萨,但以不同的方式。在我们的应用程序中,它是用户设置。现在要点披萨,我们打电话给instantiateFeature
并传递它#34;我想点披萨"或者可能正在呼叫instantiatePizzaFeature
。内部instantiateFeature
查找设置并决定是否需要创建OrderPizzaByPhoneFeature或OrderPizzaByEmailFeature。我们得到Feature
并将其称为doSomething
,这正是我们想要做的。现在,如果我们想要添加一些新的订单类型OrderPizzaByPigeonMailFeature
,我们需要做的就是在instantiateFeature
中添加用户设置和几行。订购代码仍然可以正常工作,它从不知道Feature
子类。好吧也许它知道有一些订购披萨功能,但从来不知道它们中有多少存在。