gpt4 book ai didi

c# - 为什么需要将派生类的对象赋值给基类来调用方法?

转载 作者:太空狗 更新时间:2023-10-30 00:40:43 25 4
gpt4 key购买 nike

我有一个名为 Shape 的基类和一个派生自 Shape 的派生类 Rectangle。

class Shape
{
public virtual void Draw()
{
//Draw the Shape
Console.WriteLine("Draw the Shape");
}
}
class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("Draw Rectangle");
}
}

我有一个非常基本的疑问,即在调用我的派生类的方法时我做了这样的事情。

Shape r1 = new Rectangle();
r1.Draw();

但是如果我想调用 Rectangle 类的方法,我总是可以这样做。

Rectangle r2 = new Rectangle();
r2.Draw();

我的问题是,当我们总是可以使用易于理解和实现的第二种方法时,为什么我们需要使用第一种方法。?

最佳答案

两种方法都是正确的,都可以工作。在这两种情况下,Rectangle 类的 Draw 方法都会被调用。

关于为什么要使用第一种方法的第一个场景是,当您有某种集合并且想要一次绘制它们时。假设您添加了更多派生类,例如 CircleTriangle,它们也覆盖了 Draw 的基本实现。那么以下仍然是一个有效的场景:

//We know that our collection will contain various shapes.
List<Shape> shapes = new List<Shape>();

//This is okay because all the specific shapes inherit from the Shape class.
shapes.Add(new Triangle());
shapes.Add(new Rectangle());
shapes.Add(new Circle());

//We can safely draw all shapes, because all shapes have a Draw-method.
//If they haven't implemented their own, the Draw-method of the Shape class will be called.
foreach(Shape shape in shapes)
shape.Draw();

要记住的一件事是,在上面的示例中,我们将所有特定对象视为类型 Shape。这实质上意味着在该用法中,每个对象都不知道任何特定于类的实现。假设您向 Rectangle 添加了一个 NumberOfCorners 属性:

class Rectangle : Shape
{
public Rectangle() {
NumberOfCorners = 4;
}

public override void Draw()
{
Console.WriteLine("Draw Rectangle");
}

public int NumberOfCorners { get; set; };
}

那么以下将不起作用,因为 Shape-class 没有 NumberOfCorners-property:

Shape shape = new Rectangle();
Console.WriteLine(shape.NumberOfCorners); //This will cause an error.

但是,特定实例仍然在 Rectangle 实例的深处,这意味着它可以工作:

Console.WriteLine((shape as Rectangle).NumberOfCorners); //This is fine, provided that shape is not null.

关于c# - 为什么需要将派生类的对象赋值给基类来调用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24996500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com