【问题标题】:How to achieve Multiple inheritance in C#?如何在 C# 中实现多重继承?
【发布时间】:2013-07-04 12:59:56
【问题描述】:

我的应用程序中有以下代码。

public class GeneralInfo
        {
            private string _id;
            private string _name;           

            public string id
            {
                set
                {
                    _id = value;
                }
                get
                {
                    return _id;
                }
            }

            public string name
            {
                set
                {
                    _name = value;
                }
                get
                {
                    return _name;
                }
            }

        }

       public class SecureInfo
       {
           private string _password;

           public string password
           {
               set
               {
                   _password = value;
               }
               get
               {
                   return _password;
               }
           }

       }


public class User
{
}

我需要在上面的代码中应用多重继承,即。类 GeneralInfo、SecureInfo 属性应该可以在用户类中访问。

我知道使用接口可以实现多重继承。但是我需要在接口中限制的基类中定义属性。

我怎样才能做到这一点?

【问题讨论】:

  • 不是。 C# 中没有多重继承。如果接口不能为您解决问题,那么您就别无选择了。
  • 您确定需要继承吗?您说“类 GeneralInfo,SecureInfo 属性应该可以在用户类中访问”。所以也许 GeneralInfo 和 SecureInfo 应该只是用户类的属性......
  • 您确定需要它吗?看起来用户是一个 GeneralInfo,但我认为它有一个 SecureInfo
  • 组合优于继承。用户不是 SecureInfo。这就是继承的意思。用户拥有 SecureInfo。见en.wikipedia.org/wiki/Composition_over_inheritance
  • @RaphaëlAlthaus 因为这些类将在许多其他类(如 User)中重用。例如:GeneralInfo 将在可重用的 User、books、sites 类中通用。

标签: c# .net inheritance interface


【解决方案1】:

C# 不支持多重继承。但是,您可以通过多个接口来实现。

public interface ISecureInfo 
{

}

public interface IGeneralInfo 
{

} 

public class UserClass : ISecureInfo, IGeneralInfo {

}

【讨论】:

  • 一个类不“继承”接口。他们实施它们。
  • 从接口继承类是公认的术语,有时更准确。
【解决方案2】:

您最好将数据封装在类中,而不是在这里尝试使用某些东西进行多重继承。请参阅this question 了解有关此的一些论点。

【讨论】:

    【解决方案3】:

    您可以通过基于接口的继承来实现这一点:

    public interface IGeneralInfo 
    {
        String Id { get; set; }
        String Name { get; set; }
    }
    
    public interface ISecureInfo
        String Password { get; set; }
    }
    
    
    public class User : IGeneralInfo, ISecureInfo
    {
        // Implementation of IGeneralInfo
        public String Id { get; set; }
        public String Name { get; set; }
    
        // Implementation of ISecureInfo
        public String Password { get; set; }
    }
    

    或者,更进一步,通过合成:

    public interface IGeneralInfo 
    {
        String Id { get; set; }
        String Name { get; set; }
    }
    
    public class GeneralInfo : IGeneralInfo
    {
        public String Id { get; set; }
        public String Name { get; set; }
    }
    
    public interface ISecureInfo
        String Password { get; set; }
    }
    
    public class SecureInfo : IGeneralInfo
    {
        public String Password { get; set; }
    }
    
    public class User : IGeneralInfo, ISecureInfo
    {
        private GeneralInfo generalInfo = new GeneralInfo();
        private SecureInfo secureInfo = new SecureInfo();
    
        public String Id { 
            get { return generalInfo.Id; }
            set { generalInfo.Id = value; } 
        }
        public String Name { 
            get { return generalInfo.Name; }
            set { generalInfo.Name = value; } 
        }
    
        public String Password { 
            get { return secureInfo.Password; }
            set { secureInfo.Password = value; } 
        }
    }
    

    【讨论】:

      【解决方案4】:

      根据您的示例描述,您可能想要使用封装:

      public class Info{
          GeneralInfo general;
          SecureInfo secure;
      ...
      }
      

      【讨论】:

        【解决方案5】:

        您不能在 C# 中进行多重继承,因为它不像 C++ 那样受支持。在 C# 中,您可以为其使用接口并实现方法和属性。例如,你可以有一个基类

        public abstract class Entity
        {
            public string Name { get; set; }
        
        }
        

        你也可以有一些接口:

        public interface IPrint
        {
           void Print();
        }
        
        public interface IGenerate
        {
           void Generate();
        }
        

        并像使用多重继承一样使用它(但它不是,它只是一个单一的继承和接口)

        public class User : Entity, IPrint, IGenerate
        {
           public void Print()
           {
             // some code
             // here you could access Name property, because it is on base class Entity
           } 
        
           public void Generate()
           {
             // some code
           } 
        }
        

        您可以使用抽象来实例化它:

        Entity e = new User();
        IPrint p = new User();
        IGenerate g = new User();
        User u = new User();
        

        如果你需要实现,你可以做一个层次继承,例如:

        用户从继承自实体的人继承。

        public class Entity
        {
           public int Id { get; set; }
        
        
           public void Method()
           {
              // some code
           }
        }
        
        public class Person : Entity
        {
           public string Name { get; set; }
        
           public void AnotherMethod()
           {
              // some code
           }
        }
        
        public class User : Person
        {
           public string Password { get; set; }
        
           public bool CheckUser(string name, string passworkd)
           {
              // some code
           }
        }
        

        【讨论】:

        • 不定义方法和属性,使用Interface对我来说毫无用处。
        【解决方案6】:

        我认为最好的办法是将接口的实现和你最后拥有的真实类分开。 我的意思是类似于桥接模式。 您的类(将实现多个接口)只会将方法调用委托给真正的实现,您可以在单独的地方使用,并且只能使用一次。

        【讨论】:

        • 你能举个例子吗?
        【解决方案7】:

        您也可以使用这样的方法。与使用多重继承相比,您将得到相同的结果。这样,如果您不需要 SecureInfo 的东西(即书籍和其他东西),您可以只继承实体。不过,正如其他人所说,我认为在这种情况下作曲会做得更好......

        class User : SecuredEntity { }
        
        abstract class SecuredEntity : Entity, ISecureInfo
        {
            public string Password { get; set; }
        }
        
        abstract class Entity : IGeneralInfo
        {
            public string ID { get; set; }
            public string Name { get; set; }
        }
        
        interface IGeneralInfo
        {
            string ID { get; set; }
            string Name { get; set; }
        }
        
        interface ISecureInfo
        {
            string Password { get; set; }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-15
          • 2011-11-21
          • 2015-02-12
          • 2020-07-01
          相关资源
          最近更新 更多