0

我觉得自己像个傻瓜。我做编码员已经有一段时间了,我之前没有遇到过这种语言,我想,我一直在用“附加”的东西覆盖构造函数。所以,我截断了一些类解释:

public enum Flags : ushort
{
   Item = 1,
   Player = 2
}

public class Item
{
    private Flags _flags;
    private int _owner;
    private String _pwd;

    public Item(Flags flags, int owner, String pwd = null)
    {
        _owner = owner;
        _flags = flags;
        _pwd = pwd;
    }
}

public class Connection
{
    ... stuff irrelevant to question
}

因此,当玩家登录时,我希望能够获取Item具有 typePlayer并具有连接的后代 - 实际上它只是一个项目。

所以我作为初学者这样做了:

public class Player : Item
{
    public Connection Conn;
}

它说:

项目不包含采用 0 个参数的构造函数

好吧,在我眼里,我从来没有说过。。玩家永远不会被“创建”,只从项目中复制,一个现有项目,我正在添加一个额外的属性(并不是说这将作为我的代码保留) ,但这是一个起点).. 所以,我不想手动将实际的 20 多个属性从一个复制到另一个。实际上我希望能够使用

Player p = (Player)item_wanted;

然后为其分配一个连接..p Player永远不会直接创建。我不想将连接分配给项目,因为它只是活跃的玩家,从技术上讲,一个玩家可以拥有多个连接。

当然,第一个愚蠢的想法是构造函数

Public Payer(Item i)
{
    this = (Player) i;
}

是的,可悲的是不能这样做,可以吗?:( 但实际上,这几乎就是我想要的!

在你问之前,我确实考虑过将项目添加到连接中......但从逻辑上讲,你不会那样想的......

那么,我该如何绕过呢?我想添加一个属性并将其称为其他属性...

好的,我明白为什么它说关于讲师,很失望它没有与原始课程中可用的课程相匹配,但是很好,我明白了。但是,由于原始项目已经存在,我不想要副本。我想添加功能......我放弃了。这个问题可以关闭。**

4

6 回答 6

3

第一个问题:Item 具有私有属性,因此后代将无法访问_flags。如果您将它们声明为受保护,后代将​​可以访问,但您将无法使用这样的构造函数:

    public Player(Item i) : base(i._flags,i._owner,i._pwd)

因此,如果您公开 Item 属性,这将起作用:

public enum Flags : ushort

{
   Item = 1,
   Player = 2
}

public class Item
{
    public Flags _flags;
    public int _owner;
    public String _pwd;


public Item(Flags flags, int owner, String pwd = null)
 {
  _owner=owner;
  _flags=flags;
  _pwd=pwd;
 }
}

public class Connection
{
    public Connection()
    {
    }
}
public class Player : Item
{
    public Connection Conn;
    public Player(Item i) : base(i._flags,i._owner,i._pwd)
    {
        // and add your "additional thing"
        // This calls the base constructor, and then you can add codes...
    }

}

所以,你可以这样做:

    Item p = new Item(Flags.Item,12);  // Item is something existing
    Player x = new Player(p);

请注意,Player x 和 Item p 并不相同。玩家 x 是从项目 p 创建的,因此修改 p。不会影响 x.. 所以代码:

    Item p = new Item(Flags.Item,12);
    Player x = new Player(p);         // instead of: Player p = (Player)item_wanted;
    p._owner = 20;

将显示 20(作为 p._owner)和 12(作为 x._owner)。在基于项目创建新玩家后,您可以“忘记”该项目。

于 2012-09-14T10:55:24.923 回答
2

原因是您的子类构造函数隐式调用了父类的默认构造函数。在您的父类中,您没有定义任何带有 0 参数的构造函数,这就是您收到此错误的原因。

尽管您还没有为您的Player类定义任何构造函数。它将假定一个默认构造函数,如以下调用。

Player() : base()
{
}

要解决此问题,您可以在基类中创建一个空的默认构造函数,Item或者使用构造函数在子类中使用关键字调用特定构造base函数。

Public Payer(Item i) :base(arg1,arg2,arg3)
{

}

使用构造函数 - MSDN

在派生类中,如果未使用 base 关键字显式调用基类构造函数,则隐式调用默认构造函数(如果有) 。

于 2012-09-14T10:03:32.537 回答
2

如果您继承自Item您需要从以下位置调用其构造函数Player

public Player(Flags flags, int owner, String pwd = null) : base(flags, owner, pwd) 
{
   // Do something else
}

或者你必须定义一个没有参数的构造函数Item

于 2012-09-14T10:04:29.810 回答
1

将构造函数添加到以下项:

public Item() { };
于 2012-09-14T10:05:26.270 回答
1

如果您希望Player从 复制属性Item,那么继承可能不是要走的路。您可以使用组合:

class Player
{
    Item item;
    public Player(Item item)
    {
        this.item = item; // store reference to item here, it will point to the same object you used for construction, no copying needed later
    }
}

您也不必公开item为公共属性来调用player.Item.Flags等,您可以为您的Player类创建包装器属性:

class Player
{
    Item item;
    public Player(Item item)
    {
        this.item = item; // store reference to item here, it will point to the same object you used for construction, no copying needed later
    }

     public string Name { get { return item.Name; } } // etc...
}
于 2012-09-14T10:05:27.907 回答
1
public class A
{
   private int _p;
   public A(int param) { _p = param;}
}

public class B : A 
{
    public B(int param) : base(param)
    {
    }

    public int x { get; set; }
}

如果您有 A ( var item = new A(1);) 的实例,则无法将其转换为 B。但如果您有 B ( var player = new B(1);) 的实例 - 您可以将其转换为 A:

var casted = (A)item;

那么,您所说的Player 永远不会仅从项目(现有项目)中“创建”是什么意思?

于 2012-09-14T10:14:54.740 回答