在C#抽象中设置构造函数

时间:2012-08-10 21:21:34

标签: c# constructor abstract-class scope

请考虑以下非常基本的 C#代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();

            for (int i = 1; i <= 100; i++)
            {
                int num = random.Next(1000);
                string it_type;

                if (num == 666)
                {
                    System.Console.Write("Antichrist/satanistic trips get. Enjoy! ");
                    JonSkeet technician = new JonSkeet(); // Needs more Super::$tatic
                    technician.setup();
                    it_type = technician.getITType();
                }
                else
                {
                    Whisperity technician = new Whisperity();
                    technician.setup();
                    it_type = technician.getITType();
                }

                System.Console.WriteLine(it_type + "... Prepare for next iteration.");
            }

            System.Console.ReadLine();
        }
    }

    abstract public class ITTechnician
    {
        protected string itt_type = "Noname person.";
        protected bool isJonSkeet = false;

        public string getITType()
        {
            return this.itt_type;
        }

        abstract public void setup();
    }

    public class JonSkeet : ITTechnician
    {
        public override void setup()
        {
            this.itt_type = "Jon Skeet";
            this.isJonSkeet = true;
        }
    }

    public class Whisperity : ITTechnician
    {
        public override void setup()
        {
            this.itt_type = "Whisperity";
            this.isJonSkeet = false;
        }
    }
}

我如何能够以抽象类(abstract public void?)需要它的方式设置构造函数,并且我不必调用technician.setup();,因为构造函数需要注意设置两个内部变量。如果我调用类函数与类本身相同的名称,我会收到以下错误:

  

错误1'Whisperity':成员名称不能与其附件

相同

另外,我的另一个问题是优化问题。有没有办法在technician构造之外定义if,所以可以执行以下类似的操作:(这将省略classType technician = new classType();行两次,或者它是否在C#中无法通过?)

string it_type;
// Register 'technician' as a variable here.
if (num = 666)
{
    technician = new JonSkeet();
}
else
{
    technician = new Whisperity();
}

it_type = technician.getITType();
System.Console.WriteLine(it_type + "...");

3 个答案:

答案 0 :(得分:2)

回答您的问题

您可以在抽象类中提供带参数的构造函数。

abstract public class ITTechnician
{
    public ITTechnician(string itt_type, bool isJonSkeet)
    {
        this.itt_type = itt_type;
        this.isJonSkeet = isJonSkeet;
    }
}

构建一个JonSkeet(如果它只是那么容易!)

JonSkeet jon = new JonSkeet("Jon Skeet", true);

有关课堂设计的建议

另一方面,我知道这是一个示例问题,但如果基类保存的信息可以区分继承它的类,那么您就不会很好地使用面向对象。

具体来说,这种设计会引导你做像

这样的事情
ITTechnician itt = GetSomeInstance();

if (itt.IsJonSkeet)
{
    BehaviorA();
else
{
    BehaviorB();
}

做一些像

这样的事情要干得多
abstract public class ITTechnician
{
    public abstract void Behavior();
    // ...
}

public class JonSkeet
{
    public override Behavior()
    {
        // Do awesome things
    }
}

允许将上述代码写为

ITTechnician itt = GetSomeInstance();
itt.Behavior();

答案 1 :(得分:0)

  

我如何能够以抽象的方式设置构造函数   上课需要它,我不需要打电话   technician.setup()

您不需要构造逻辑来强制abstract类的行为,反之亦然。 Abstract类定义了孩子必须遵循的stuf。

如果在abstract类中创建一个简单的参数 ctor,它会初始化您需要的变量,每当构造child对象时,abstract的默认值为{{之前将调用1}},因此将执行初始化。

更清楚:

public class Child : Base 
{

    public Child(int x){
     "Child".Dump();
    }
}

public abstract class Base
{

    public Base() {

        //INIT VARIABLES HERE
       "Base".Dump();
    }
}

使用像

这样的结构

vaar ch = new Child();生成结果

"Base"
"Child"

如果这不是您所要求的,请澄清。

答案 2 :(得分:0)

要在运行时发现类型,请使用GetType()。无需创建自己的类型字符串字段。

除了类结构中的内在类型之外,唯一不同的是IsJonSkeet。我们可以使用.NET属性来实现它,与使用Getter和Setter的传统私有/受保护字段相比,这是一种更现代和更具表现力的方式。

abstract public class ITTechnician
{
    public bool IsJonSkeet { get; protected set; }
    protected ITTechnician()
    {
        this.IsJonSkeet = false;
    }
}

public class JonSkeet : ITTechnician
{
    public JonSkeet()
    {
        this.IsJonSkeet = true;
    }
}

public class Whisperity : ITTechnician
{
}

现在已经删除了你的itt_type字符串字段,Whisperity与基类相同,因此不需要构造函数进行任何初始化 - 它会自动获取其父级的IsJonSkeet值。

+1也是Eric J的课程设计技巧。您应该使用层次结构的设计来封装不同的内容,这使您的调用代码更加透明,并且代码库将来更容易扩展。