Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the correct alternative to static method inheritance?

I understand that static method inheritance is not supported in C#. I have also read a number of discussions (including here) in which developers claim a need for this functionality, to which the typical response is "if you need static member inheritance, there's a flaw in your design".

OK, given that OOP doesn't want me to even think about static inheritance, I must conclude that my apparent need for it points to an error in my design. But, I'm stuck. I would really appreciate some help resolving this. Here's the challenge ...

I want to create an abstract base class (let's call it a Fruit) that encapsulates some complex initialization code. This code cannot be placed in the constructor, since some of it will rely on virtual method calls.

Fruit will be inherited by other concrete classes (Apple, Orange), each of which must expose a standard factory method CreateInstance() to create and initialize an instance.

If static member inheritance were feasible, I would place the factory method in the base class and use a virtual method call to the derived class to obtain the type from which a concrete instance must be initialized. The client code would simple invoke Apple.CreateInstance() to obtain a fully initialized Apple instance.

But clearly this is not possible, so can someone please explain how my design needs to change to accommodate the same functionality.

like image 843
Tim Coulter Avatar asked Sep 04 '09 15:09

Tim Coulter


People also ask

What can I use instead of static methods?

You can use the full power of inheritance and overriding since your methods are no longer static. You can use the constructor to do any initialisation, including associating SQL with the table (SQL that your methods can use later). This should make all your problems above go away, or at least get much simpler.

What is static method inheritance?

Static methods do not use any instance variables of any object of the class they are defined in. Static methods take all the data from parameters and compute something from those parameters, with no reference to variables. We can inherit static methods in Java.

Are static methods inherited in C#?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor.

Can we use static in inheritance?

Static methods in Java are inherited, but can not be overridden. If you declare the same method in a subclass, you hide the superclass method instead of overriding it. Static methods are not polymorphic. At the compile time, the static method will be statically linked.


2 Answers

One idea:

public abstract class Fruit<T>     where T : Fruit<T>, new() {     public static T CreateInstance()     {         T newFruit = new T();         newFruit.Initialize();  // Calls Apple.Initialize         return newFruit;     }      protected abstract void Initialize(); }  public class Apple : Fruit<Apple> {     protected override void Initialize() { ... } } 

And call like so:

Apple myAppleVar = Fruit<Apple>.CreateInstance(); 

No extra factory classes needed.

like image 74
Matt Hamsmith Avatar answered Sep 22 '22 05:09

Matt Hamsmith


Move the factory method out of the type, and put it in its own Factory class.

public abstract class Fruit {     protected Fruit() {}      public abstract string Define();  }  public class Apple : Fruit {     public Apple() {}      public override string Define()     {          return "Apple";     } }  public class Orange : Fruit {     public Orange() {}      public override string Define()     {          return "Orange";     } }  public static class FruitFactory<T>  {      public static T CreateFruit<T>() where T : Fruit, new()      {          return new T();      } } 

But, as I'm looking at this, there is no need to move the Create method to its own Factory class (although I think that it is preferrable -separation of concerns-), you can put it in the Fruit class:

public abstract class Fruit {     public abstract string Define();     public static T CreateFruit<T>() where T : Fruit, new()    {         return new T();    }  } 

And, to see if it works:

    class Program     {         static void Main( string[] args )         {             Console.WriteLine (Fruit.CreateFruit<Apple> ().Define ());             Console.WriteLine (Fruit.CreateFruit<Orange> ().Define ());              Console.ReadLine ();         }             } 
like image 41
Frederik Gheysels Avatar answered Sep 22 '22 05:09

Frederik Gheysels