Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与显式类型转换/子类化相关的OOP问题_C#_Oop_Inheritance - Fatal编程技术网

C# 与显式类型转换/子类化相关的OOP问题

C# 与显式类型转换/子类化相关的OOP问题,c#,oop,inheritance,C#,Oop,Inheritance,这个问题与面向对象设计的概念有关 在下面的示例代码(C#)中,我有一个抽象基类功能,它有两个子类:子功能1和子功能2。在我的主程序中,我想通过将相应的参数(类名称为字符串)赋予唯一的方法instanceFeature()来实例化它们 当我运行此代码时,我得到一个错误,该错误基本上表明类型OOP\u example.Feature无法隐式转换为OOP\u example.SubFeature1,因为已经存在显式转换 using System; using System.Collections.Ge

这个问题与面向对象设计的概念有关

在下面的示例代码(C#)中,我有一个抽象基类
功能
,它有两个子类:
子功能1
子功能2
。在我的主程序中,我想通过将相应的参数(类名称为字符串)赋予唯一的方法
instanceFeature()
来实例化它们

当我运行此代码时,我得到一个错误,该错误基本上表明类型
OOP\u example.Feature
无法隐式转换为
OOP\u 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()
)存在于我的所有类中

实现这一目标的常见方法是什么?谁能告诉我一个最佳实践


谢谢大家!

实例化功能方法的返回类型是
功能
,因此如果要将其分配给
子功能1
,则需要强制转换:

        SubFeature1 subObj1 = (SubFeature1)myOrga.instantiateFeature("SubFeature1");
        SubFeature2 subObj2 = (SubFeature2)myOrga.instantiateFeature("SubFeature2");
但是无论如何,如果您已经知道该方法将返回的具体类型,那么使用工厂方法是没有意义的;您还可以直接实例化具体类。工厂方法的要点通常是从实际实现中抽象调用代码:

        Feature subObj1 = myOrga.instantiateFeature("SubFeature1");
        Feature subObj2 = myOrga.instantiateFeature("SubFeature2");

作为旁注,在您的
组织
类中,您应该将
obj
声明为局部变量,而不是字段。将其设置为字段意味着
实例化功能
方法不是线程安全的。

我认为您尝试使用的概念不是真正的继承,而是多态性,您应该做的是创建一个具有类型功能的对象,并与新功能1/2关联。在其中一个上使用方法时,它将首先搜索“executive”类型。

实例化功能
返回
功能
,该功能可以是
子功能1
子功能2
。如果您编写
subfeature1a=myOrga.instancefeature(“SubFeature2”)?编译器无法确定,因此它向您显示了一个错误。这种抽象基类的目的是定义一些真正重要的部分,这些部分足以让您在不考虑当前正在使用的子类的情况下工作。所以你要做的就是设计这样的
Feature
基类并编写代码,只使用
Feature
变量

编辑,文本太大,无法发表评论


让我给你看一个我所说的小例子。假设我们有一些子功能,其中一个订购比萨饼。现在我们有了子类:OrderPizzaByPhoneFeature、OrderPizzaByEmailFeature。他们两人都点了比萨饼,但方式不同。在我们的应用程序中,它是一个用户设置。现在要订购比萨饼,我们调用
实例化功能
并传递它“我想订购比萨饼”,或者调用
实例化比萨饼功能
。Inside
InstanceFeature
查找设置并决定是否需要创建OrderPizzaByPhoneFeature或OrderPizzaByEmailFeature。我们得到
功能
并称之为
doSomething
,它正是我们想要做的。现在,如果我们想添加一些新的订单类型
orderpizzabyDigeMailFeature
,我们需要做的就是在
InstanceFeature
中添加用户设置和几行。排序代码仍然可以正常工作,它从不知道
Feature
子类。嗯,也许它知道有一些订购比萨饼的功能,但不知道它们有多少。

您有一些不同寻常的功能-您希望相同的方法返回不同的类型。通常,如果
instantialefeature
返回
Feature
或任何派生类,您不应该从工厂外关心这些问题。。。如果需要区分,请考虑具有唯一返回类型的单独方法。在玩游戏时,考虑现有的DI框架来处理对象的创建。是的,但这正是我不想要的。我不希望每个子类都有一个单独的方法。没有办法做到这一点吗?对我来说,期待基于字符串的不同类型是个坏主意(主要是因为需要转换/释放强类型)。。。考虑< <代码> T实例化(字符串)< /代码>是否适用于您……是的,我想您是对的。多态性似乎正是我试图使用的。我不太明白你的描述。你能给我举个例子吗?我建议你保留你的继承,但当你实例化你的对象时,使用功能作为声明类型,使用新的子功能作为执行类型(功能my_Feature=new SubFeature();),当对对象调用一个方法时,它将在执行类型(子功能)中寻找该方法如果您想了解更多关于多态性的信息,也许会更好地解释一下^^^当我分配
obj=new SubFeature1()
?在组织中,代码似乎是正确的,但在主例程中,您将对象声明为子功能,而不是功能。我认为你应该把它们声明为特征。这可能就是为什么你的编译器对你大喊大叫的原因。我的编译器不会抱怨,就像托马斯·列夫斯克建议的那样,当我进行转换时<代码>子功能1子功能1=(子功能1)myOrga.InstanceFeature(“子功能1”)Feature1
Feature2
Feature3
,。。。不使用继承。然后,我就不需要
组织了
。不,我建议将
实例化特性
返回值当作基类-
特性
来处理。设计
功能
时,任何调用
实例化功能
的人都不会在意