实例化一个继承对象
对于继承还是比较新的,所以我需要一些帮助。目前,我有一项任务是创建一个使用3种武器继承的基本游戏。我的基类:实例化一个继承对象
public class Weapons : MonoBehaviour
{
public int rateOfFire;
public string myName;
public Weapons(string Name)
{
myName = Name;
}
}
而子类中的一种:
public class Rifle : Weapons
{
public Rifle(string Name)
: base(Name)
{
myName = Name;
rateOfFire = 5;
}
}
我的第一个问题来了这样一个事实,如果我连这样做对吗?
我的第二个问题是如何将这些实例化到我的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);
}
}
}
我的第一个问题来了这样一个事实,如果我连这样做对吗?
非常接近。我们看看吧。
public class Weapons : MonoBehaviour
{
我认为这是来自给定基类型的这种类型的Unity限制。通常,人们永远不会说武器是一种“monobehaviour”,无论如何。
有没有武器不是更具体的武器?不,所以这应该是一个抽象类。
类应该命名为单数,除非类本身代表一组事物。这应该是“武器”,而不是“武器”。
abstract class Weapon: MonoBehaviour
{
继续前进。
public int rateOfFire;
我们已经陷入困境。公共字段在C#中是不好的代码味道。如果你想有一个公共属性,则使其成为一个属性:
3210更多的鼻子上,但:射速仅适用于远程武器。你在基类中有这个,暗示它适用于所有武器。你不会开刀。
public string myName;
再次,公共领域,不好。使它成为一个财产。不要称之为myName
。叫它它是什么:Name
:
public string Name { get; set; }
继续前进。
public Weapons(string Name)
{
myName = Name;
}
使用驼峰的参数,PascalCase的性质:
public Weapon(string name)
{
Name = name;
}
将其命名为过改变吗?如果没有,请将其设置为只读属性。
public string Name { get; }
(取决于你使用的是什么版本的C#这可能不合法。尝试{ get; private set; }
如果不工作)。
那名可以在构造函数中设置意味着每实例的武器有一个名字。是对的吗?这看起来不正确。有没有名为鲍勃剑的剑,还有名为“Stormbringer”的剑和什么?我原以为这个名字会与这个类型相关联,而不是与一个给定的实例相关联。我期望这个名字是一个抽象的属性,被派生类型覆盖。
public abstract string Name { get; }
移动到派生类型:
public Rifle(string Name)
: base(Name)
{
myName = Name;
rateOfFire = 5;
}
这被弄乱了。您已经在基类构造函数中设置了名称;不要再设置它!为什么是由基地设定的名称,而是由派生的电力公司设定的火灾率?要么火速应该是派生类型的属性,要么应该与名称一起传入。
让我们摆脱它们,只是在派生类中重写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"; } }
}
有意义吗?
我的第二个问题是如何将这些实例化到我的Unity场景中?
这是更好地让每StackOverflow上的问题一个问题,因为通常会发生什么是第二个问题没有得到回答。就像我没有在这里回答它。
为什么在基类中有一个抽象属性而不是在构造函数中设置的具体属性更好?我这样问,是因为当我拥有对于对象必不可少的不变属性时,我总是在这两种解决方案之间犹豫不决,比如'Name'或'Id'。最近我开始使用混凝土材料,以保证其不变性。 –
@LucaCremonesi:如果这个属性真的是不变的,那么我认为这是更好的解决方案。在OP所在的“游戏”领域,可能会有一些游戏规则,比如说,根据上下文来改变火焰的速度,就好像你在夜间在潮湿的屋顶上一样。在这种情况下,人们可能会争辩说,财产首先不是正确的,而虚拟方法会更好。或者说房地产应该是“未修改的火灾率”,然后这是对更复杂政策的不变的投入。我的观点是:这取决于情况。 –
在继承的类中调用'myName = Name;'是没有必要的,因为您调用基类并且基类已经这样做了。 – Icemanind
为什么你需要在这里继承?你不使用任何继承的优势。 Unity3d中的每个对象都是从MonoBehaviour继承而来的。 – Valentin
@Valentin因为这就是任务所要求的,正如他所说的。 – Asik