简体   繁体   中英

C# How to instantiate derived objects from abstract base class

Let's say I have an abstract base class, Shape and then three derived classes: Triangle, Rectangle and Pentagon. The derived classes must be created based on a requirement so I could have several of each of the derived classes. The base class has quite a few fields and I was looking for a way to set the base class properties only once and then just set the different fields for the derived classes later. Since you cannot instantiate an abstract class, what is the best way to do this? I was thinking maybe create another class that derives from Shape that only has the properties of Shape, set those properties and then cast it but this seems inefficient and has code smell written all over it. Can someone suggest a better way? Thanks. Below I have written some pseudo code for the situation

public abstract class Shape
{
    public int x, y, z;
}

public class Triangle : Shape
{
   public int a, b, c       
}

public class Facade : Shape
{
}

private Facade InitializeBaseProperties()
{
    Facade f = new Training
    {
       x = 1, y = 2, z = 3
    };
    return f;
}

private void someMethod()
{
   var tmp = InitializeBaseProperties();
   Triangle triangle = tmp;
}

It's true that you can't instantiate an abstract class, but that doesn't mean an abstract class can't have a constructor.
Use a constructor in the abstract class and chain it to the concrete implementation classes constructors:

 public abstract class Shape
 {
      protected int _x, _y, _z;
      protected Shape(int x, int y, int z)
      {
          _x = x;
          _y = y;
          _z = z;
      }
 }

Then, in the derived class:

 public class Triangle : Shape
 {
      public Triangle (int x, int y, int z, int a, int b) : base(x,y,z)
      {
          A = a;
          B = b;
      }

      public int A {get;}
      public int B {get;}
 }

Something like the following is the closest to your current way of doing things. In this setup your InitializeBaseProperties now takes a shape and sets properties on it. You would then pass your triangle to it after it has been created.

private void InitializeBaseProperties(Shape shape)
{
    shape.x = 1;
    shape.y = 2;
    shape.z = 3;
}

private void someMethod()
{
   Triangle triangle = new Triangle();
   InitializeBaseProperties(triangle);
}

This solution requires that the initialization of a Triangle doesn't actually use any of the properties that you are setting in the InitializeBaseProperties method since they won't actually be there yet.

If you need those properties to be there when you construct the object the only way to do this would be to pass them into the constructor of each of your shapes. Other answers have already addressed this so I will not repeat what they have to say.

I should note that I have deliberately provided an answer as close as possible to your original code since I don't know what your actual code looks like. Setting values in the constructor as others have done may well be the better solution but only you can judge what is best in your actual code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM