0

考虑以下非常基本的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 + "...");
4

3 回答 3

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();
于 2012-08-10T21:25:13.123 回答
0

我如何能够以抽象类需要它并且我不必调用technical.setup() 的方式设置构造函数

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

如果您在类中创建一个简单的无参数ctor abstract它会初始化您需要的变量,那么无论何时child构造对象,都会在之前调用默认的ctor abstract,因此将执行初始化。

为了更清楚:

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"

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

于 2012-08-10T21:29:47.103 回答
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 值。

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

于 2012-08-10T22:29:28.217 回答