【问题标题】:Correctly accessing parameters from a " : Base" constructor从“:Base”构造函数正确访问参数
【发布时间】:2015-07-12 01:08:21
【问题描述】:

情况

我正在使用我在本学年学到的一些 OOP 实践制作一个基于文本的小型游戏,我这样做的原因主要是为了改进我目前知道的 OOP,并希望在有经验的帮助下改进我的一些实践用户。

所以,用外行的话来说,我目前有一个扩展“Enemy”的“Ork”类,而“Enemy”正在扩展“Entity”

public class Ork : Enemy

public class Enemy : Entity

我有“Enemy”类,因为我打算制作许多独特的敌人对象类型,而不仅仅是“Ork”,通过当前的设置,我可以用相同的方式制作“Elf”或“Human”。 (而且以后添加新类型要容易得多)Enemy 有自己的构造函数。

public Enemy(string[] Droplist, int Defaultgold, string Weaknesses, string Resistances, string[] Taunts, string Aggro, string Critchance, string Threshold, string Name, string Type,
        string Spawnzone, string _Class, int Defaultlevel, int Maxlevel, string trait, int str, int agi, int dex, int hel, int man)
    {
        //make a new entity instance.
        entity = new Entity();

        //Set all the local variables to the passed in parameters.

        setEntity(Name, Type, Spawnzone, _Class, Defaultlevel, Maxlevel, trait, str, agi, dex, hel, man);

        droplist = Droplist;
        defaultgold = Defaultgold;
        weaknesses = Weaknesses;
        resistances = Resistances;
        taunts = Taunts;
        aggro = Aggro;
        critchance = Critchance;
        threshold = Threshold;

}

如您所见,我将传入参数设置为局部变量,并使用 setEntity 为我完成部分工作。我还有一个“Entity”类,原因是,并不是所有有“Stats”的东西都是敌人,所以我有“Entity”作为中间人。

问题

问题出在这行类的末尾,即 Ork 类。

在其他程序中,例如我的 Hillracing 程序,我的类似类的构造函数如下所示:

public JuniorMember(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
            string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues, string parentalConsent)
            : base(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub,
            gender, memexp, yearofbirth, monthofbirth, dayofbirth)
        {

所以,简单地说,问题是,在这个程序中,我正在查看相似数量的参数,而就我个人而言,查看这些参数我感觉好像我没有正确执行此操作。

我在 Hillracing 中给出的示例完美无缺,但我只是想知道这是否是最好的方法,因为参数列表看起来很乱,感觉好像我正在创建之前已经创建的东西.我的意思是,创建 Ork 对象所需的 90% 的信息来自其他地方。

编辑

由于制作了 cmets,我删除了我在敌人类中制作的新实体,我现在拥有以下 Enemy 类:

public class Enemy : Entity
{

    private string[] droplist;

    private int defaultgold;

    private string weaknesses;

    private string resistances;

    private string[] taunts;

    private string aggro;

    private string critchance;

    private string threshold;


    public string[] Droplist { get { return droplist; } set { droplist = value; } }
    public int Defaultgold { get { return defaultgold; } set { defaultgold = value; } }
    public string Weaknesses { get { return weaknesses; } set { weaknesses = value; } }
    public string Resistances { get { return resistances; } set { resistances = value; } }
    public string[] Taunts { get { return taunts; } set { taunts = value; } }
    public string Aggro { get { return aggro; } set { aggro = value; } }
    public string Critchance { get { return critchance; } set { critchance = value; } }
    public string Threshold { get { return threshold; } set { threshold = value; } }




    public void setEntity(string EnName, string EnType, string EnSpawnzone, string En_Class, int EnDefaultlevel, int EnMaxlevel, string Entrait, int Enstr, int Enagi, int Endex, int Enhel, int Enman)
    {


        setStats(Enstr, Enagi, Endex, Enhel, Enman);

        Name = EnName;
        Type = EnType;
        Spawnzone = EnSpawnzone;
        _Class = En_Class;
        Defaultlevel = EnDefaultlevel;
        Maxlevel = EnMaxlevel;
        trait = Entrait;

    }

    public Enemy(string[] Droplist, int Defaultgold, string Weaknesses, string Resistances, string[] Taunts, string Aggro, string Critchance, string Threshold) 

        :base(Name,Type,Spawnzone,_Class,Defaultlevel,Maxlevel,trait,str,agi,dex,hel,man)
    {

        //Set all the local variables to the passed in parameters.

        setEntity(Name, Type, Spawnzone, _Class, Defaultlevel, Maxlevel, trait, str, agi, dex, hel, man);

        droplist = Droplist;
        defaultgold = Defaultgold;
        weaknesses = Weaknesses;
        resistances = Resistances;
        taunts = Taunts;
        aggro = Aggro;
        critchance = Critchance;
        threshold = Threshold;

}

我的问题是,此时我不知道如何从Entity 获取信息,我无法访问Name,Type,Spawnzone,etc,etc 变量,因为它们需要对象引用。

【问题讨论】:

  • 你可以让方法不带任何参数,这些参数会被转换成你的类内部的属性,如果这些属性在你的实体之间是通用的,你可以为此创建一个接口
  • Enemy 扩展 Entity,你的 Enemy 类中不应该有实体变量,因为它本身就是一个实体。
  • 检查编辑,我从敌人类中删除了实体实例。
  • 这在本示例中可能并不完全相关,因为它不是讨论的重点,但一般来说,避免从属性返回数组是一种很好的做法。考虑使用集合,或将这些属性更改为方法。 Link from MSDN

标签: c# class oop constructor


【解决方案1】:

注意:我看到您刚刚进行了编辑以阐明您的 Enemy 类扩展了 Entity。然后我不明白为什么要在 Enemy 构造函数中实例化 Entity 类。 EntityEnemy之间的逻辑关系是什么? EnemyEntity 的一种吗?或者,Enemy 是否有 Entity

也许您可以考虑将Entity 实例传递给Enemy 构造函数,以避免必须将Entity 类的所有单独组件传递给Enemy 构造函数。像这样的:

public class Entity {
    // other code

    public Entity(string Type, string Spawnzone, string _Class, int Defaultlevel, int Maxlevel, string trait, int str, int agi, int dex, int hel, int man) {
        // move setEntity code here.
    }

    // other code
}

public class Enemy {

    // other code

    public Enemy(string[] Droplist, int Defaultgold, string Weaknesses, string Resistances, string[] Taunts, string Aggro, string Critchance, string Threshold, string Name, Entity entity) {
            this.entity = entity;

            droplist = Droplist;
            defaultgold = Defaultgold;
            weaknesses = Weaknesses;
            resistances = Resistances;
            taunts = Taunts;
            aggro = Aggro;
            critchance = Critchance;
            threshold = Threshold;
    }

    // other code
}   

【讨论】:

  • EnemyEntity 的一种类型。就像PlayerItem 可能是Entity 的一种类型。这样做的逻辑推理是 Entity 类包含将来将由 ItemEnemyPlayer 使用的项目。就像统计数据一样,一切都有统计数据。很抱歉造成混乱。
【解决方案2】:

Entity 应该是 Enemy 扩展的基类(具有并非所有实体都具有的附加统计信息)。从Enemy 的构造函数中,您应该调用父Entity 构造函数。这是有道理的,因为Enemy "is a(n)" Entity.

而目前,您的设置是这样的,Enemy“有一个(n)”Entity,这是没有意义的。


编辑

你已经有了这个:

public class Ork : Enemy

我是说,你也需要这个:

public class Enemy : Entity

而 C# 我认为类基类构造函数会自动生成,因此您无需执行任何其他操作。只需对 Entity 构造函数中的所有 Entitys 和 Enemy 中的 Enemys 执行所有通用的操作,等等。

【讨论】:

  • 敌人确实扩展了实体。 public class Enemy : Entity
  • 你确定吗?目前,您似乎正在Enemy 的构造函数中创建Entity 的新实例。
  • 不一定是“错误的”,但这不是扩展类,不。扩展课程就像您在 Enemy 或 Ork 中所做的那样。要完成层次结构,您需要执行以下操作:Entity to Enemy to Ork,而不是在 Enemy 中创建 Entity 对象。
  • 好的,假设我删除了那行代码,我会用什么替换它?来自敌人的“:Base”到实体?
【解决方案3】:

我假设您的Enemy 类包含Entity 的实例。在您的情况下,这是错误的做法。如果您的Enemy 类由Entity 扩展,那么您可以使用其构造函数将通用值设置为父类。就像您在 HillRacing 程序中所做的一样。

(确保您的Enemy 类没有Entity 类型的成员。如果它是Enemy 的基类)

public class Entity 
{
    public string Type;
    public string Spawnzone;
    public string _Class;
    public string Defaultlevel;
    public string Maxlevel;
    public string Trait;
    public string str;
    public string agi;
    public string dex;
    public string hel;
    public string man;

    public Entity(string Type, string Spawnzone, string _Class, int Defaultlevel, int Maxlevel, string trait, int str, int agi, int dex, int hel, int man) 
    {
        this.Type = Type;
        this.Spawnzone = Spawnzone;
        this._Class = _Class;
        this.Defaultlevel = Defaultlevel;
        this.Maxlevel = Maxlevel;
        this.Trait = trait;
        this.str = str;
        this.agi = agi;
        this.dex = dex;
        this.hel = hel;
        this.man = man;
    }

}

public class Enemy 
{
    public string[] droplist;;
    public int defaultgold;
    public string weaknesses;
    public string resistances;
    public string[] taunts;
    public string aggro;
    public string critchance;
    public string threshold;


    public Enemy(string[] Droplist, int Defaultgold, string Weaknesses, string Resistances, string[] Taunts, string Aggro, string Critchance, string Threshold, string Name, string Type, string Spawnzone, string _Class, int Defaultlevel, int Maxlevel, string trait, int str, int agi, int dex, int hel, int man ) 
    : base(Type, Spawnzone, _Class, Defaultlevel, Maxlevel, trait, str, agi, dex, hel, man)
    {

        droplist = Droplist;
        defaultgold = Defaultgold;
        weaknesses = Weaknesses;
        resistances = Resistances;
        taunts = Taunts;
        aggro = Aggro;
        critchance = Critchance;
        threshold = Threshold;
    }

}

【讨论】:

  • 你能举个例子吗?
猜你喜欢
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
  • 1970-01-01
  • 2020-07-11
  • 2018-12-08
  • 2013-05-07
  • 1970-01-01
相关资源
最近更新 更多