类和对象继承
本文关键字:继承 对象 | 更新日期: 2023-09-27 17:56:40
>更新
好的,所以我正在玩类和继承,我正在尝试做一些我以前在源代码C++的游戏中看到过的事情,我想知道这里是否有人可以帮助我理解我将如何使用 C# 做到这一点。
我想做的是两件事:
首先,当我创建某个类的对象时,我想将一个整数传递给构造函数和该整数以确定将初始化的子句。
像这样: 职业新Voc = 新职业(1);1 将选择具有该 VocationID 的第一个子类或子类。
第二件事,我已经有一个从生物类继承的玩家类,但我希望玩家类本身包含一个职业对象。所以我可以设置职业,当我这样做时,属性会发生变化,并且玩家具有不同的属性......这是尝试遵循我所说的示例代码,希望有人理解我的意思。
好的,所以我现在收到一个错误。无法隐式转换类型Mage' to
职业'
这就是我得到的...
职业.cs
using UnityEngine;
using System.Collections;
public enum VocationType { Mage, Warrior }
public class Vocation
{
}
public static class VocationFactory
{
public static Vocation CreateVocation(VocationType type)
{
switch (type)
{
case VocationType.Mage:
{
return new Mage();
break;
}
}
}
}
public class Mage
{
public string Name = "Mage";
public Mage()
{
}
}
播放器.cs
using UnityEngine;
using System.Collections;
public class Player : Creature
{
public uint Level {get; set; }
public uint Dexterity {get; set; }
public uint Vitality {get; set; }
public uint Intelligence {get; set; }
public uint Strength {get; set; }
public ulong Experience {get; set;}
public Player()
{
var voc = VocationFactory.CreateVocation(VocationType.Mage);
Level = 1;
Health = 500;
MaxHealth = 100;
Mana = 50;
MaxMana = 100;
Experience = 0;
Dexterity = 0;
Vitality = 0;
Intelligence = 0;
Strength = 0;
}
}
不应从基类创建对象。 请改用工厂,也许使用枚举来定义类型。
如果您从 Dmitry 对上一个问题的回答开始,则可以创建一个实例化对象的工厂类。例如:
public enum VocationType { Mage, ... }
public static class VocationFactory
{
public static Vocation CreateVocation(VocationType type)
{
switch (type)
{
case VocationType.Mage:
{
return new Mage();
break;
}
}
throw new Exception($"You did not implement type '{type}'.");
}
}
然后这样称呼它:
var voc = VocationFactory.CreateVocation(VocationType.Mage);
我认为你不希望Vocation
成为Player
的子类型,而是Player
拥有的东西。一个Player
甚至可能有多个职业。这反映了您显示的代码。
这是无法做到的,但有办法解决它。
构造函数需要指定类型,并且不能指定祖先,必须指定要实例化的实际类型。因此,new Vocation(1)
将只创建该实例,一个Vocation
实例,而不是子类。
解决此问题的一种方法是使用 case
语句:
switch (vocation)
{
case 1:
return new Mage();
case 2:
return new Sorceror();
}
但这不是好的设计,我不会那样做。在 C# 中,你有枚举,所以至少使用这些枚举:
enum VocationType
{
Mage,
Sorceror
}
switch (vocation)
{
case Mage:
return new Mage();
case Sorceror:
return new Sorceror();
}
这还是不好。这里的问题是,你正在寻找的实际上是一种创建模式,而不是一个编程技巧。
你真正想要的是一个可以创建你想要的任何类型的播放器的工厂。
在 c# 中执行此操作的更好(可能仍然不是最佳)方法是具有工厂方法的泛型,您可以将要实例化的实际Type
传递给该方法,如下所示:
public class PlayerFactory
{
public Player Create<V>()
where V : Vocation
{
Player p;
p = new Player();
p.SetVocation<V>();
return p;
}
}
SetVocation<V>()
方法是:
public class Player : Creature
{
private Vocation ChosenVocation;
public Player()
{
}
public void SetVocation<V>()
where V : Vocation
{
ChosenVocation = new V();
}
}
您现在可以按如下方式创建这些实例:
switch (vocation)
{
case Mage:
return PlayerFactory.Create<Mage>();
case Sorceror:
return PlayerFactory.Create<Sorceror>()
}
为什么要大惊小怪?
您希望尽快将自己从 1
或 Vocation.Mage
等代码中删除,并切换到实际类型(即实现的代码)。上述方法允许您通过以下方式轻松扩展代码:
- 向
Vocation
枚举添加职业; - 将
case
添加到switch()
; - 实现职业(例如
Sorceror
类)。
对于First
要求,您可以使用一个parameter
进行constructor
,并在构造函数的实现中随意调用该类。
public class Class1
{
public Class1(int i)
{
// Your implementation logic goes here
}
}
下面是您的更新代码,我认为它将满足您的Second
要求。
public class Vocation
{
public Vocation()
{
}
public Vocation(int i)
{
}
}
public class Player : Creature
{
Vocation v;
public Player(int i)
{
}
public void SetVocation(int value)
{
// if you wanna set it to value
v = new Vocation(value);
}
}
对于第二点,只需创建一个Player
和一个新的Vocation
(基于 Patrick 的答案):
var player = new Player { Vocation = VocationFactory.CreateVocation(VocationType.Mage) };
这假设您的 Player
类上有一个属性Vocation
:
class Player : Create
{
public Vocation Vocation { get; set; }
}