2012-09-14 123 views
0

我觉得自己就像一个完整的dork。我一直是一个编码器,而且我还没有遇到过这种语言,我想,我一直在用“额外”的东西覆盖构造函数。所以,我截断了一些类解释:后裔类的构造函数问题

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后代其类型Player,并具有连接 - 因为实际上这只是一个项目。

所以,我做这个作为首发:

public class Player : Item 
{ 
    public Connection Conn; 
} 

它说:

项目不包含一个构造函数0参数

好了,在我眼里,我从来没有说过它..玩家永远不会被“创造”只从项目复制,现有的项目,我添加到它,一个额外的属性(不是这是什么将保持为我的代码,但它是一个起点)。因此,我不想手动将实际的20多个属性从一个复制到另一个。现实我希望能够使用

Player p = (Player)item_wanted; 

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

当然,第一愚以为是

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

呀可悲的是不能做的,一个构造函数,对吗? :(但实际上,这几乎我想要的!

你问之前,我也考虑增加项目连接...但是在逻辑上你不会想到这样的说法轮...

所以,我怎么得到它呢?我想添加一个属性,并把它称为别的东西...

好的,我得到它为什么说关于教练,失望它没有去与原来的可用的但很好,我知道了,但是,由于原始项目已经存在,我不想复制,我想添加功能...我放弃了。此问题可以被关闭。**

+0

没有定义构造函数的类是隐含给定的默认构造函数。当你继承它时,假设隐式默认构造函数会调用基类的默认构造函数,但是你的基类没有。 – Jodrell

+0

我认为这也可能是设计问题。为什么你的'Player'需要继承'Item'?它是模型'是'的关系(即“播放器”是'Item')吗? – Bartosz

+0

如果你曾经玩过泥土/粪便,这将会更有意义。玩家是数据库中的一个项目,唯一不同的是它被登录为并具有玩家标志。所以,一旦连接,我想要更容易访问,我的连接有一个项目附加到它,但现实是球员有一个连接..你想说“Player.NotifyLine”找不到球员的连接,并告诉连接发送线路。项目只存在一次。因此,将所有属性复制到播放器,意味着您需要不断地更新基础项目。真实的项目视为播放器 – BugFinder

回答

2

原因是你的子类构造函数含蓄调用你的父类的默认构造函数。在你的父类中,你还没有定义任何带有0个参数的构造函数,这就是为什么你会得到这个错误。

虽然您尚未为您的Player类定义任何构造函数。它将假设一个默认构造函数,如下面的调用。

Player() : base() 
{ 
} 

要解决此问题,你可以在你的基类Item创建一个空的默认构造函数或致电用关键字base具体构造与构造你的子类。

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

} 

Using Constructors - MSDN

在派生类,如果显式使用碱关键字基础类构建不叫 ,那么默认的构造,如果 有一个,被称为隐含

+0

正如我所说,技术上我不会做一个“新”球员,只是复制一个项目,有没有办法做到这一点? – BugFinder

+0

@BugFinder,然后在你的播放器类中定义一个私有构造函数,并在你的Item类中定义一个空构造函数 – Habib

+0

它告诉我,我不能使用This =(Player),因为这是只读的 - 我曾试过。 – BugFinder

2

如果从Item继承你需要从Player调用构造函数:

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

或者你必须定义与Item无参数的构造函数。

+0

的问题,我并不需要用其他语言,而不是重新构造构造函数,我对那里的构造函数感到满意。是不是还有更优雅的如何做到这一点? – BugFinder

+0

我想没有其他办法,也许使用反射,但肯定不会很优雅! :) – Alessandro

+0

不,这不会:(看起来这么简单的事情想做,似乎奇怪,它的如此难以管理 – BugFinder

1

添加一个构造函数来的项目:

public Item() { }; 
+0

我不想运行犯规,然后潜在地创建一个没有设置的项目..球员将永远是一个Item +连接,即使连接未设置,或丢失,我想将它们识别为一对..我永远不会创建一个空的播放器,它将始终设置为当前项目。我可以这样做吗? – BugFinder

1

如果你希望你的PlayerItem复制的属性,然后继承可能不是要走的路。你可以使用组成:

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... 
} 
+0

As我说,玩家永远是一个整体项目,没有办法做(玩家)没有构造函数和手动复制所有设置,所以在更新项目的情况下,我不必记得更新播放器? – BugFinder

+0

然后,组合可能要走,检查更新的答案 – Bartosz

+0

我曾经想过,但现实是,我不想结束Player.item.name等代码,因为它的Player.Name,Player.flags ..它与ite 100%相同米,它有一个活跃的连接..我也不想保存我的物品连接,所以我不想添加连接到物品,因为从长远来看,90%的物品不会成为玩家。 – BugFinder

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; 

那么,你是什么播放器意味着将永远不会被“创造”只有从项目复制现有项目

3

第一个问题:项目具有私有属性,因此后代将无法访问_flags。如果你声明它们加以保护,descendats将有机会获得,但你将不能够使用这样的构造:

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

所以,如果你做项目的属性公开,这将工作:

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

注意,该玩家x和物品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)。在基于物品创建新玩家之后,您可以“忘记”物品。

+0

谢谢..接近,但仍然不是我想要的。 – BugFinder