初学者到C#:如何进行构造函数链接,覆盖和使用:this /:base?

时间:2017-07-27 08:10:58

标签: c# inheritance constructor overloading chaining

我去年学过Java,但我认为编写构造函数时遇到了问题。遗憾的是,我对C#中的重载和链接工作非常困惑,甚至是它的基本概念。

我已经看过:基地被用于继承,但我不确定如何。 我已经看到了:这在很多地方得到了应用,它总是让我感到困惑。

以下是一些代码的示例:this(为了参数而制作的公共变量没有setter / getter)。

public class Person
{
    public string firstName;
    public string lastName;
    public string height;
    public int age;
    public string colour;

public Person():this("George", "Seville", "45cm", 10, "Black")
    {
    // This is the default constructor, and we're defining the default 
values.
     }

public Person(string firstName, string lastName, string height, int age, 
string colour)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.height = height;
        this.age = age;
        this.colour = colour;
    }

}}

我只能理解第一个构造函数是如何被使用的,例如制作一个简单的对象" Person"会给它默认值。据我所知,这是我的意思。此代码未完成,因为它显示了2个默认构造函数。我希望能够为每个可用的变量进行过载和链接,即1个参数,2个参数......因此它们都会过载并适当地链接。

所以它应该是(可能不对)看起来像这样:

public Person():this("George", "Seville", "45cm", 10, "Black")
    {
    // This is the default constructor, and we're defining the default 
values.
     }

public Person(string firstName):this(firstName, "George", "Seville", "45cm", 
10, Black)
    {
        this.firstName = firstName;
    }

public Person(string firstName, string lastName):this(firstName, lastName, 
"Seville", "45cm", 10, Black)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }

当然我不确定上面的代码是否有意义,但是我已经看到了一些带有构造函数的类:对于每个构造函数都有这个,并且每个构造函数都链接到它下面的构造函数,直到它们为止。用户可以使用任何定义的参数组合创建一个Object。

至于:基地,这完全让我感到困惑。这是我在网上找到的一个例子:

    public class Circle:Shape
{
    public Circle():this(Color.Black, new Point(0,0), 1)
    {
    }

    public Circle(Color Colour, Point Position, double Radius):base(Colour, 
Position) 
    {
        this.Radius = Radius;
    }

我认为:base指的是父类,但我不确定为什么以及如何。另外,为什么:这是在第一个构造函数中使用而不是:base?

我非常困惑的两个方面。使用:this和:base并准确理解构造函数链接和重载是如何工作的。如果我的问题太抽象,请告诉我。我试图尽可能具体。

非常感谢你的支持和时间。非常感谢!

5 个答案:

答案 0 :(得分:4)

我会尝试尽可能简单地解释它。

构造函数重载

这里没什么新东西,就像重载任何其他方法一样 - 你只需要相同的名称,但需要不同的签名(意味着不同的参数传递给构造函数)。

构造函数链接

这是通过使用关键字this来完成的 - 就像你问题中的代码示例一样 顺便说一句,我通常用它来从最精细的构造函数转到最简单的构造函数 示例代码:

public class Person
{
    public Person()
    {
        Children = new List<Person>();
    }

    public Person(string firstName)
        : this()
    {
        this.FirstName = firstName;
    }

    public Person(string firstName, string lastName)
        : this(firstName)
    {
        this.LastName = lastName;
    }

    public string FirstName { get; }
    public string LastName { get; }
    public IEnumerable<Person> Children { get; }
}

当然,使用构造函数链接将默认值设置为属性是一种有效的设计,我在需要时自己使用它,但通常情况并非如此。

关键字base

此关键字始终引用基类(或父类)。 当重写方法和属性时,你会看到很多 当涉及构造函数时 - 您的假设是正确的 - 它确实引用了基类(或父类)。 因此,当在构造函数中使用时(如在Circle示例中),您可以控制派生(或子)类构造函数将执行的基础构造函数的重载。
因此,例如,如果您的基类包含三个构造函数,您可以选择要调用哪一个。

除非另有说明,否则c#会将派生类的构造函数链接到基类的默认构造函数 请注意,如果从没有默认(意味着:无参数)构造函数的类继承,则必须在构造函数中指定: base(...),即使基类只有一个构造函数(因为这是你唯一的方法)可以将所需的参数传递给它。)

答案 1 :(得分:2)

一般来说,: this(...)指的是当前类的构造函数。在您的示例中,这可用于避免代码重复。从逻辑的角度来看,我认为给出的例子并没有多大意义,但它是合法的C#和 - 基本上 - 如何使用: this(...)

第二个例子是一个更符合逻辑的或者是连贯的,因为默认构造函数提供了合理的默认值来传递给参数化的构造函数。

这是默认的构造函数,它为要传递给参数化构造函数的值创建合理的默认值:

public Circle():this(Color.Black, new Point(0,0), 1)

这是参数化构造函数,它将基类所需的参数传递给Shape的构造函数:

public Circle(Color Colour, Point Position, double Radius):base(Colour, Position) 

如果您需要标准圈,可以使用

创建一个
var shape = new Circle();

另一方面,如果您需要在特定位置使用特定颜色和特定半径的圆,则可以使用参数化构造函数创建一个圆

var shape = new Circle(Color.Silver, new Point(1,2), 5);

答案 2 :(得分:1)

  

我认为:base指的是父类,但我不确定为什么以及如何

base是访问父类成员的关键字。

1)var p = base.Property;将从父类

访问字段或属性

2)base.Method();将从父类

访问方法

3)base(..)将从父类

访问构造函数
  

为什么:这是在第一个构造函数中使用而不是:base?

this是访问同一类的成员的关键字。有3个参数定义Circle的属性。 CircleShape仅共享1个属性:color。所以默认构造函数调用同一个类Circle的更专业的构造函数(这就是this()的原因),第二个构造函数将共享属性color传递给要处理的父类用。

public class Circle:Shape
{
    public Circle():this(Color.Black, new Point(0,0), 1)
    {
    }

    public Circle(Color Colour, Point Position, double Radius):base(Colour, 
Position) 
    {
        this.Radius = Radius;
    }
}

答案 3 :(得分:0)

在您的示例中,“base”指的是Shape(颜色颜色,Point Position),“this”指的是Circle(Color Color,Point Position,double Radius)。

答案 4 :(得分:0)

第一个构造函数正在访问定义中的第二个构造函数,这就是它使用的原因:this。

第二个构造函数正在使用基类中定义的构造函数,这就是它使用base的原因:

如果使用以下方法创建Circle实例:

simulation(&array);

它将使用第一个构造函数,它将调用第二个构造函数(添加它需要的参数),这将调用基类中的构造函数。