类和对象继承

本文关键字:继承 对象 | 更新日期: 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>()
}

为什么要大惊小怪?

您希望尽快将自己从 1Vocation.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; }
}