请解释 Shape r = new Square() 的结果以及为啥 Square 的方法不可用
Posted
技术标签:
【中文标题】请解释 Shape r = new Square() 的结果以及为啥 Square 的方法不可用【英文标题】:Please explain the outcome of Shape r = new Square() and why Square's methods aren't available请解释 Shape r = new Square() 的结果以及为什么 Square 的方法不可用 【发布时间】:2021-10-20 09:42:29 【问题描述】:我正在研究 Jeff Fritz 的 c# tutorial videos,并且有一些类似这样的代码使用抽象类:
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
有人可以解释一下吗?
-
当我们执行
Shape r = new Square();
时实际创建了什么?是Shape
还是Square
?
为什么GetType
返回Square
却找不到Square
类中的方法?
Jeff 说(如果我理解正确的话)“‘Shape` 是用 Square 的足迹创建的”,然后继续前进。
Fiddle
【问题讨论】:
"它是形状还是正方形?"两者都是,因为所有 Square 对象也是 Shape 对象。 您创建使用new
关键字初始化的内容,在本例中为 Square
实例。但是您将它分配给它的基本类型Shape
的变量。通过这种方式,您隐藏了它是Square
的事实。你总是可以将它转换回Square
,然后你也可以使用SquareOnlyMethod
。因此,即使它仍然是 Square
,编译器也不允许使用在 Square
中定义的方法,如果它被声明为 Shape
,因为不是每个 Shape
都有这个方法。
【参考方案1】:
您看到的问题始于以下行 Shape r = new Square();
,因为即使您正在创建 Square 但使用基本类型。我假设 Jeff 试图向您展示的概念是 多态性,可以在此处查看形状问题的更好示例https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/polymorphism。
在 Microsoft 示例中,您可以看到基类为任何派生类(形状)提供了通用功能,以利用、扩展或覆盖。因此,您可以潜在地将不同 Shape 子代的单个数组视为 Shapes,并跨任何子 shape(因此有多种形式)访问或调用方法(虚拟覆盖)。
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();
【讨论】:
谢谢。这是实例化期间“装箱”的一个例子吗?创建了一个 Square 但只展示基类 Shape 的方法?让我困惑的是 GetType 位。 不,当您需要使用值类型代替引用类型时会发生装箱,例如object integer = 1
。在这里,所有类型都是引用类型,因此不会发生装箱。
@EvilDr GetType 返回运行时类型,因为运行时的实例类型是 Square - 这就是您将看到的。查看 docs.microsoft.com/en-us/dotnet/api/… 和 docs.microsoft.com/en-us/dotnet/api/… 这些是了解差异的好参考。以上是关于请解释 Shape r = new Square() 的结果以及为啥 Square 的方法不可用的主要内容,如果未能解决你的问题,请参考以下文章
请高手指点:回归分析中的“multiple r ”“R Square ”“Adjusted R Square”“标准误差 ”是啥意思?
计算形状Shape(圆Circle,矩形Square ,正方形Rectangle)的面积周长