实例化一个继承的对象

J T*_*aff 0 c# inheritance

继承还是比较新的,所以我需要一些帮助.目前,我有一项任务是创建一个使用3武器继承的基本游戏.我的基类:

public class Weapons : MonoBehaviour
{
    public int rateOfFire;
    public string myName;

    public Weapons(string Name)
    {
        myName = Name;
    }
}
Run Code Online (Sandbox Code Playgroud)

其中一个子课程:

public class Rifle : Weapons
{
    public Rifle(string Name) 
        : base(Name)
    {
        myName = Name;
        rateOfFire = 5;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是,如果我做得对吗?

我的第二个问题是如何将这些实例化为我的Unity场景?我写了一个切换武器的方法,这是我的播放器脚本上的一个数组,所以我会在这里插入一个实例化的行还是创建另一个方法?缺少一些线条,但这是正确的:

public GameObject[] weapons;
public int currentweapon = 0;
private int invweap;
void Start()
{
    //Managing weapons
    invweap = weapons.Length;
    SwitchWeapon(currentweapon);
}
void SwitchWeapon(int index)
{
    for (int i = 0; i<invweap;i++)
    {
        if (i == index)
        {
            weapons[i].gameObject.SetActive(true);
        }
        else
        {
            weapons[i].gameObject.SetActive(false);
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 7

我的第一个问题是,如果我做得对吗?

很接近了.我们看看吧.

public class Weapons : MonoBehaviour
{
Run Code Online (Sandbox Code Playgroud)

我认为这是Unity的限制,这种类型来自给定的基类型.通常人们永远不会说武器是一种"单一行为",不管是什么.

是否有任何武器不是更具体的武器?不,所以这应该是一个抽象的类.

除非类本身代表一组事物,否则应将类命名为单数.这应该是"武器",而不是"武器".

abstract class Weapon: MonoBehaviour 
{
Run Code Online (Sandbox Code Playgroud)

继续.

public int rateOfFire;
Run Code Online (Sandbox Code Playgroud)

我们已经遇到麻烦了.公共字段在C#中是一种糟糕的代码味道.如果您想要一个公共财产,那么将其作为财产:

public int RateOfFire { get; set; }
Run Code Online (Sandbox Code Playgroud)

更多关于鼻子:火速只适用于远程武器.你在基类中有这个,暗示它适用于所有武器.你不开剑.

public string myName;
Run Code Online (Sandbox Code Playgroud)

再次,公共领域,不好.把它变成一个财产.别叫它myName.称之为它Name:

public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

继续.

public Weapons(string Name)
{
    myName = Name;
}
Run Code Online (Sandbox Code Playgroud)

使用camelCase作为参数,使用PascalCase作为属性:

public Weapon(string name)
{
    Name = name;
}
Run Code Online (Sandbox Code Playgroud)

名字会改变吗?如果没有,请将它作为一个只有房产.

public string Name { get; }
Run Code Online (Sandbox Code Playgroud)

(取决于您使用的C#版本可能不合法.{ get; private set; }如果不起作用,请尝试.)

可以在ctor中设置名称意味着武器的每个实例都有一个名称.是对的吗?这似乎不对.有没有名为Bob's Sword的剑,以及名为"Stormbringer"的剑和诸如此类的剑?我原以为名称会与类型相关联,而不是与给定的实例相关联.我希望该名称将是一个抽象属性,由派生类型覆盖.

public abstract string Name { get; }
Run Code Online (Sandbox Code Playgroud)

继续导出类型:

public Rifle(string Name) 
    : base(Name)
{
    myName = Name;
    rateOfFire = 5;
}
Run Code Online (Sandbox Code Playgroud)

这搞砸了.您已经在基类构造函数中设置了名称; 不要再设置了!为什么名称由基础ctor设定,但由衍生的ctor设定的射速?火灾率应该是派生类型的属性,或者应该与名称一起传递.

让我们摆脱它们,只是在派生类中重写fire的名称和速率抽象属性.让我们改进类型层次结构,以便武器基类不包括仅对远程武器通用的东西.

所以,把它们放在一起:

public abstract class Weapon : MonoBehaviour
{
  public abstract string Name { get; }
}

public abstract class RangedWeapon : Weapon
{
  public abstract int RateOfFire { get; }
}

public class Rifle : RangedWeapon
{
  public override string Name { get { return "rifle"; } }
  public override int RateOfFire { get { return 5; } }
}

public class Sword : Weapon
{
  public override string Name { get { return "sword"; } }
}
Run Code Online (Sandbox Code Playgroud)

合理?

我的第二个问题是如何将这些实例化为我的Unity场景?

最好在StackOverflow上针对每个问题提出一个问题,因为通常会发生的是第二个问题没有得到解答.就像我在这里没有回答的那样.