类和对象继承

时间:2016-07-13 09:54:07

标签: c# class inheritance

已更新

好的,所以我正在玩类和继承,我正在尝试做一些我以前在一个源代码是C ++的游戏中做过的事情,我想知道这里有人能帮我理解我是怎么做的用C#。

我想做的是两件事:

首先当我创建某个类的对象时,我想将一个整数传递给构造函数,并使用该整数来确定将初始化哪个sublcass。

像这样:职业newVoc = new Vocation(1); 并且1将选择具有该VocationId的第一个sublcass或子类。

第二件事,我已经拥有一个从Creature Class继承的玩家类,但我希望玩家类本身包含一个Vocation对象。所以我可以设置职业,当我进行属性更改并且播放器具有不同的属性时...这是一个示例代码,尝试使用我所说的内容,希望有人理解我的意思。

好的,我现在收到一个错误。无法隐式转换类型Mage' to职业'

这就是我得到的......

Vocation.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()
    {

    }
}

Player.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;
    }
}

4 个答案:

答案 0 :(得分:5)

您不应该从基类创建对象。请改用工厂,也可以使用枚举来定义类型。

如果从Dmitry's answer on your previous question开始,可以创建一个实例化对象的工厂类。例如:

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);

答案 1 :(得分:2)

我认为您不希望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类)。

答案 2 :(得分:0)

对于第二点,只需创建一个Vocation和一个新var player = new Player { Vocation = VocationFactory.CreateVocation(VocationType.Mage) }; (根据Patrick的回答):

Vocation

这假设您在Player - 类上有一个属性class Player : Create { public Vocation Vocation { get; set; } }

{{1}}

答案 3 :(得分:0)

对于First要求,您可以constructor一个parameter,并在构造函数的实现中调用您想要的类。

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);
    }
}