主类USER和子类PLAYER,如何PLAYER = USER? C#

时间:2014-12-27 14:42:04

标签: c# inheritance subclass mainclass

我正在制作第一个服务器 - 客户端应用程序,我需要你的帮助 客户必须进行自我验证,然后才能玩一些游戏 所以我有USER和PLAYER课程:USER比较所有用户注册和PLAYER comprends玩游戏的用户(有PLAYER_GAME1,PLAYER_GAME2等)。
在USER内部我有名称,姓氏,身份证等等 在PLAYER内部,我需要拥有用户的加分,加点,比赛时间等等。

实际上:

     public class USER
{
        public string name, surname, ID, password, IP;
        WALLET wallet;
        bool login;
        datetime lastAccess;
        TcpClient socket;    
        Thread receiveMessages;//this receive message for log-in
        ...*other 30 proprieties*
     public USER(string n,string s,string _id,string pw)
    {
     *inizialize all variables*
    }
   }

   public class PLAYER
    {
      public USER user;
        Thread receiveMessages;
        int points;
        bool online;
        ...*other proprieties*

     public PLAYER(USER u)
     {
      user=u;
     *inizialize all variables*
     }
    }

所以要获得我必须做的名字:

PLAYER p= new PLAYER(new USER(...));
string name=p.user.name;

我认为更聪明的是制作USER的PLAYER子类,当用户想要玩游戏时我会扩展"具有玩家礼仪的班级用户,所以我需要这样做:

            public class USER
            {
                protected string name, surname, ID, password, IP;
                WALLET wallet;
                bool login;
                datetime lastAccess;
                TcpClient socket;    
                Thread receiveMessages;//this receive message for meneage the game
                ...*other 30 proprieties*

             public USER(string n,string s,string _id,string pw)
            {
             *inizialize all variables*
            }
           }

           public class PLAYER : USER
            {
                Thread receiveMessages;
                ...*other proprieties*

             public PLAYER():base()// here, what could i do?
             {
             *inizialize all PLAYER variables*
             }
            }

所以为了得到我想做的名字:

PLAYER p= new PLAYER();
p=exixtingUser;
string name=p.name;

我知道SUBCLASS = MAINCLASS是不可能的,所以我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

据我所知,您希望根据Player信息创建User角色。

如果我们的课程是:

public class User
{
    public Guid Id { get; private set; }
    public string Name { get; private set; }

    public User(Guid id, string name)
    {
        Id = id;
        Name = name;
    }
}

public class Player : User
{
    public TimeSpan TimeInGame { get; set; }

    public Player(User userInfo)
        : base(userInfo.Id, userInfo.Name)
    {

    }
}

这种构造函数的用法将是:

var player = new Player(user);

您可以使用接受User信息的构造函数。您也可以撰写extension method .ToPlayer()或类似内容。

我认为您应该阅读article about inheritance on the MSDN并继续阅读Constructors articles


更新

我已经理解了你的问题,但不幸的是,没有简单的解决方案。您可以保留当前的解决方案,如果您的应用程序基于一个用户创建了许多玩家,这将是正常的。如果它是一对一的关系,你可以这样做:

public class User
{
    public Guid Id { get; private set; }
    public string Name { get; private set; }

    public User(User copyFrom)
    {
        Id = copyFrom.Id;
        Name = copyFrom.Name;
        // copy all the fields you need
    }
}

public class Player : User
{
    public TimeSpan TimeInGame { get; set; }

    public Player(User userInfo)
        : base(userInfo)
    {

    }
}

此解决方案的主要问题是您必须自己复制它,而不需要任何自动化机制。你可以在这里找到一个类似的问题:

Copying the contents of a base class from a derived class

答案 1 :(得分:0)

根据您的澄清要求,并且仅提供VMAtm扩展的优秀解决方案。

public class USER
{
   // changed to public getters so externally can be accessed
   // for read-only, but write access for USER instance or derived class (PLAYER)
   // QUESTIONABLE on public accessor on password
   public string name { get; protected set; }
   public string surname { get; protected set; }
   public string ID { get; protected set; }
   public string password { get; protected set; }
   public string IP { get; protected set; }

   WALLET wallet;
   bool login;
   datetime lastAccess;
   TcpClient socket;    
   // make this too protected AND available to player AND any others that make sense above
   protected Thread receiveMessages; //this receive message for meneage the game
   ...*other 30 proprieties*

   public USER(string nm, string sur, string _id, string pw)
   {
      name = nm;
      surname = sur;
      ID = _id;
      password = pw;

      InitUserVars();
   }

   private InitUserVars()
   {
      *inizialize all variables*
   }

}

public class PLAYER : USER
{
   // removed the Thread receiveMessages;
   // as it is avail on parent class  USER
   ...*other proprieties*

   // slightly different option, instead, call the "THIS" version of constructor
   public PLAYER(USER ui) : this(ui.name, ui.surname, ui.ID, ui.password )
   {  }

   // Now, pass same initializing parms to the USER base class so that all still runs the same.  
   public PLAYER(string nm, string sur, string _id, string pw) : base(nm, sur, _id, pw)
   {
      // by calling the "base" above, all default behaviors are handled first

      // Now, we can do whatever else specific to the PLAYER
      InitPlayerVars()
   }


   private InitPlayerVars()
   {
      *inizialize variables associated with PLAYER that is NOT part of USER baseclass*
   }
}

现在,在从用户扩展的播放器中使用相同的参数构造函数参数,您实际上可以跳转到使用parms直接创建播放器或间接通过用户通过。

PLAYER p1 = new PLAYER( "name", "mr", 123, "mypassword" );

或使用USER的INSTANCE

的结果
USER u1 = new USER( "name", "mr", 123, "mypassword" );
PLAYER p1 = new PLAYER(u1);

这有助于澄清一些多类实现的初始化吗?