简体   繁体   English

C#如何实例化抽象基类的派生对象

[英]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. 假设我有一个抽象的基类Shape,然后有三个派生类:Triangle,Rectangle和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. 我在想可能要创建另一个从Shape派生的类,该类仅具有Shape的属性,设置这些属性,然后进行转换,但这似乎效率很低,并且代码气味遍布其中。 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. 在此设置中,您的InitializeBaseProperties现在采用形状并为其设置属性。 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. 此解决方案要求Triangle的初始化实际上不使用您在InitializeBaseProperties方法中设置的任何属性,因为它们实际上尚未存在。

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. 像其他人一样在构造函数中设置值可能是更好的解决方案,但是只有您可以判断实际代码中的最佳值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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