首页 > 解决方案 > 请解释 Shape r = new Square() 的结果以及为什么 Square 的方法不可用

问题描述

我正在阅读 Jeff Fritz 的 c#教程视频,并且有一些这样的代码使用了抽象类:

public abstract class Shape {}
public class Rectangle : Shape {}
public class Square : Rectangle {
    public string SquareOnlyMethod() { return "I am a square"; }
}


public static void Main()
{
    Square s = new Square(); 
    
    Console.WriteLine(s.GetType());            // Square
    Console.WriteLine(s is Shape);             // True
    Console.WriteLine(s is Rectangle);         // True
    Console.WriteLine(s is Square);            // True
    Console.WriteLine(s.SquareOnlyMethod());   // I am a square
    
    Shape r = new Square();
    
    Console.WriteLine(r.GetType());            // Square
    Console.WriteLine(r is Shape);             // True
    Console.WriteLine(r is Rectangle);         // True
    Console.WriteLine(r is Square);            // True
    Console.WriteLine(r.SquareOnlyMethod());   // 'Shape' does not contain a definition for 'SquareOnlyMethod' and no extension method 'SquareOnlyMethod' accepting a first argument of type 'Shape' could be found
}

有人可以解释以下内容吗?

  1. 当我们这样做时,实际上创建了什么Shape r = new Square();?是一个Shape还是一个Square
  2. 为什么GetType返回Square但找不到Square类中的方法?

Jeff 说(如果我理解正确的话)“'Shape` 是用 Square 的足迹创建的”,然后继续前进。

小提琴

标签: c#abstract-classderived-class

解决方案


您看到的问题从以下行开始,Shape r = new Square();因为即使您正在创建 Square 但使用基本类型。我假设 Jeff 试图向您展示的概念是多态性,可以在这里查看形状问题的更好示例https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/多态性

在 Microsoft 示例中,您会看到基类为任何派生类(形状)提供了通用功能,以利用、扩展或覆盖。因此,您可以潜在地将不同形状子元素的单个数组视为形状,并在任何子形状(因此有多种形式)上访问或调用方法(虚拟覆盖)。

var shapes = new List<Shape>
{
    new Rectangle(),
    new Triangle(),
    new Circle()
};

// Polymorphism at work #2: the virtual method Draw is
// invoked on each of the derived classes, not the base class.
foreach (var shape in shapes)
{
    shape.Draw();
}

推荐阅读