【问题标题】:Is there Method Inheritance in C#C#中是否有方法继承
【发布时间】:2009-12-29 02:42:36
【问题描述】:

我想知道是否有像方法继承而不是整个类继承的任何特性,让我详细说明一下我要解释的内容:

class a {
   public void GetA(){
     // some logic here
}
}

class b {
    public void GetB() : new Class().GetA()
}

我知道这看起来很奇怪,但我正在阅读如何在对象组合模式中进行委托,并且出于某种原因我想到了这种模式。

【问题讨论】:

  • 其实我不是在问是否存在相同的方法,也许在 C# 中有另一种方法可以提供更好和有效的解决方案。但是整个类的继承并不是我要的。
  • 有没有实现这个的语言?
  • @GrayWizardx 当然,这种类型的事情在许多具有一流对象功能的语言中都是可能的。我知道 Python 和 JavaScript 允许你做这种事情。
  • 您希望 GetB() 调用 GetA(),还是更改 GetA() 的行为?
  • @TM 他们实际上让你这样做吗?或者你只是得到 GetB() { return (new Class()).GetA(); 的编译器语义吗? },我问是因为在继承方面,在使用方面,“方法继承”和“虚拟方法调用”之间存在很大差异,如果“a”具有静态初始化或运行时设置,请考虑副作用。

标签: c# object-composition


【解决方案1】:

如果您只想在 GetB() 中调用 GetA(),但不想在 GetB() 中定义或显式引用类 a 的实例,则可以将 GetA() 作为委托传入。

在 C# 中,有许多预定义的委托,例如 ActionFunc。或者,您可以随时滚动自己的委托以匹配方法签名。

    class a
    {
        public void GetA()
        {
            Console.WriteLine("Hello World!");
        }
    }

    class b
    {
        // No explicit reference to class a of any kind.
        public void GetB(Action action)
        {
            action();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var a = new a();
            var b = new b();

            b.GetB(a.GetA);
        }
    }

【讨论】:

  • 哇,看起来很酷,我不知道 .net 已经提供了这样的通用解决方案,我一直在创建自己的代表...
【解决方案2】:

进行组合的常用方法是在类 b 中创建一个类型为 a 的私有成员变量,并在 GetB() 中调用 a.GetA()。例如:

class a {
   public void GetA(){
     // some logic here
   }
}

class b {
    private a _a=new a();

    public void GetB()
    {
         _a.GetA();
    } 
}

另一种选择可能是定义一个名为 GetB 的委托成员变量而不是简单方法,并允许调用代码提供由 GetB() 执行的代码。

【讨论】:

  • 你能告诉我这样做有什么好处吗?谢谢。
  • @Aaron,这样做的好处与一般使用组合的好处相同。它允许您隐藏有关您的实现的更多细节,然后继承。在此示例中,B 类的调用者不需要知道您实际上是在使用 A 类来实现 GetB()。因此,它通常比继承更灵活、更松耦合。
【解决方案3】:

我能想到的最接近的事情是如何在 C# 中“继承”一个类的构造函数到其子类(或同一类的重载构造函数)的构造函数中,如下所示:

class Animal {
    public string Species { get; set; }

    public Animal(string species) {
        Species = species;
    }
}

class Human : Animal {
    public string Name { get; set; }

    public Human(string name) : base("Homo sapien") {
        Name = name;
    }
}

上述代码的行为非常简单:Human 类的构造函数本质上是在执行任何其他操作之前调用Animal 类的构造函数。为什么非构造方法不能使用相同的功能,我不确定。

【讨论】:

  • @Aaron:是的,在Human 构造函数中,“Home sapien”作为“物种”参数传递给Animal 构造函数。
【解决方案4】:

这是不可能的。如果您希望b.GetB 重用a.GetA 的功能,那么您需要实例化a 并调用a.GetA

【讨论】:

  • 同意;支持组合,而不是继承。
【解决方案5】:

稍微不同的方法是在ClassB 的构造函数中接受ClassA 的实例,而不是直接实例化它。这会将Dependency Inversion Principle 应用于@Ash 的答案:

public class ClassB
{
    private readonly ClassA _a;

    public b(ClassA a)
    {
        _a = a;
    }

    public void GetB()
    {
        _a.GetA();

        // Other logic
    }
}

【讨论】:

    【解决方案6】:
    public class Article
    {
    
     public object AddOrUpdate(params object[] paras){
    
       return null;
    
      }
    
    }
    
    public class Test:Article
    {
    
     public new object AddOrUpdate(params object[] paras){
    
       //do your logic......
    
        return base.AddOrUpdate(paras);
    
     }
    
    
    }
    

    你的意思是这个?这是一个类可以获取或设置 BASE 对象属性的属性。

    如果你使用委托,你必须用同样的逻辑做更多的工作。

    但委托可以获取不同的域对象并做更多的应用程序。

    【讨论】:

      【解决方案7】:

      如果将 GetA() 更改为静态方法,您可以简单地在 GetB() 函数中调用它:

      class a { 
         public static void GetA() { 
           // some logic here 
         } 
      } 
      
      class b { 
          public void GetB() {
            a.GetA();
          }
      } 
      

      如果 GetA() 不是静态的,那么它没有意义,因为根据定义,GetA() 需要一个对象上下文(例如,不可见的“this”指针)。您不能将对象 B 的实例传递给 A 类,因为 A 类对 B 类一无所知。

      你真正想做什么?

      【讨论】:

        猜你喜欢
        • 2010-11-10
        • 1970-01-01
        • 2011-02-26
        • 1970-01-01
        • 2013-09-06
        • 2019-06-21
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        相关资源
        最近更新 更多