是否可以从基础构造函数中获取值,这些构造函数的变量与派生构造函数中的变量不同?

时间:2015-02-25 23:18:42

标签: c# constructor

解释我想要的东西有点不同,但我希望我能解释你能理解的方式。

我有一个A类(主要类)

B类:A(继承)

C类:A

A类有这样的书面构造函数:

public A(int a, int b, int c, string d)
{
}

让我们看看B班: B类继承自A类。 在这里,我想编写另一个单独的构造函数,它具有比A中的另一个更多的可能性。

看起来像这样:

public B(int a, int b, int c, string d, int e)
{
}

现在编译器可能会返回错误,因为已删除了A类中的标准构造函数。所以,我必须这样写:

 public B(int a, int b, int c, string d, int e) : base(a, b, c, d)
    {
       /* It's working because I've added the variable "e" only.
       The other variables haven't been changed. */
    }

但是这种情况怎么样? 没有必须对A类做任何事情的C类也希望拥有自己的构造函数。它看起来像这样:

 public C(int w, int x, string y, string z) : base(a, b, c, d)
    {
         /* Class C does have completely different values than class A.
            But I'd like to have all the variables the way I've written above.
            I'd like to use variable "w" for example. But "a" should be valid 
            to use as well. How is it possible to make the variables
            a, b, c and d valid to class C? */
}

我希望您了解我希望解决的问题。

2 个答案:

答案 0 :(得分:2)

将值从外部传递给基类构造函数确实没有魔法 - 派生类必须以某种方式指定基本构造函数的所有参数,无论是直接传递还是以其他方式计算。通常,您可以从参数和一些常量值计算基础构造函数的参数:

 public C(int w, int x, string y, string z) : 
       base(w+x, x*3, 42, "Test:" + y+z) {...}

以下是对问题的代码拼图解释的答案:

  

如何使public C(int w, int x, string y, string z) : base(a, b, c, d)编译而不管结果“

为了能够编译未作为参数传递的base(a, b, c, d),您需要将它们作为静态字段/属性或在派生类中可见的const值(即在具有任何可访问性的派生类中定义或在基类中定义,具有非私有可访问性)。您不能将实例字段/属性用作每个C#规范的基本构造函数的参数(推理:此时确实没有“实例”)。

允许代码编译的示例(您还可以使用public / internal / protected访问修饰符将a,b,c,d中的任何一个移动到基类:< / p>

class C : A 
{
  static int a = 42; // static value, initialization is optional 
  static int b {get;set;} // static property ok, with default 0 value
  const int c = 44;
  const string d = "Why?";

  public C(int w, int x, string y, string z) : base(a, b, c, d) {...}
  ...

答案 1 :(得分:0)

我希望这段代码可以帮助你帮助我; - )。

首先,我正在进入主要方法。然后使用以下代码创建B类对象:

new B(global::Test.Properties.Resources.MyPlane, 100, 100, 200, 100, 10, 10);

然后我带着以下参数进入B的构造函数(还没有执行):

public B(Bitmap pathOfMovingObject, int xPositionObject, int yPositionObject, int widthOfObject, int heightOfObject, int tank_size, int life)
            : base(pathOfMovingObject, xPositionObject, yPositionObject, widthOfObject, heightOfObject)

然后它将使用以下参数进入A的构造函数:

 private PictureBox picBoxImage;     
    protected Bitmap path;
    protected int x, y, width, height;

如果我像这样将实例变量更改为静态,那么它正在工作,但我不能再创建两个B类实例:

protected static Bitmap path;
protected static int x, y, width, height;

如果我再次将静态变量更改为实例变量,那么我遇到了出现此错误报告的问题:

非静态字段,方法或属性'A.path'需要对象引用。

    public A(Bitmap pathOfMovingObject, int xPositionObject, int yPositionObject, int widthOfObject, int heightOfObject)
        {
            path = pathOfMovingObject;
            x = xPositionObject;
            y = yPositionObject;
            width = widthOfObject;
            height = heightOfObject;

picBoxImage = new PictureBox();
            picBoxImage.Image = pathOfMovingObject;
            picBoxImage.BackColor = Color.Transparent;
            picBoxImage.SetBounds(xPositionObject, yPositionObject, widthOfObject, heightOfObject);
            this.Controls.Add(picBoxImage);
        }

然后调用B的构造函数并执行块中的代码。

然后我用main方法跳回主类。创建了C类的对象。

new C(1000, 650, 5, "stackoverflow", global::Test.Properties.Resources.sky);

然后我来到C构造函数(还没有执行)。

然后我跳转到A类的构造函数并执行该块。

然后我再次来到C构造函数:

public C(int width, int height, int speed, string title, Bitmap path)

    : base(path, x, y, width, height)  -- There you can see the error...

非静态字段,方法或属性'A.path'需要对象引用。

所以,我的问题是......如何在屏幕上显示两个B类实例,并在C类中设置有效值并禁用上层错误报告? /强>