考虑到我们有三个类,Shape是基类,另外两个类Circle和Text继承自基类(Shape)。
形状.cs
namespace ObjectOriented
{
public class Shape
{
public int Height { get; set; }
public int Width { get; set; }
public int X { get; set; }
public int Y { get; set; }
public void Draw()
{
}
}
}
文本.cs
using System;
namespace ObjectOriented
{
public class Text : Shape
{
public string FontType { get; set; }
public int FontSize { get; set; }
public void Weirdo()
{
Console.WriteLine("Weird stuff");
}
}
}
圆形.cs
namespace ObjectOriented
{
public class Circle : Shape
{
}
}
我们都知道Upcasting总是成功的,我们从一个子类引用中创建一个基类的引用。
Text txt = new Text();
Shape shape = txt //upcast
和下投可抛出和 InvalidCastException 比如
Text txt = new Text();
Shape shape = txt; //upcast
Circle c = (Circle)shape; //DownCast InvalidCastException
我所困惑的是,什么是什么?状况案例 我们可能需要更新cast和object?
通常你对存储在例如列表中的对象使用upcasting。(共享基础类型,甚至 Object
可以使用)
List<Shape> shapes = new List<Shape>();
shapes.Add((Shape)new Text()); // <-- the upcast is done automatically
shapes.Add(new Circle());
在下料的时候,你需要检查是否是正确的类型。
foreach(Shape shape in shapes)
{
if(shape is Circle)
{
Circle circle = (Circle)shape;
// do something..
}
}
有一点是: Circle
和 Text
都是 Shape
但你不能施放 Circle
到 Text
. 这是因为这两个类都在扩展 Shape
类,并添加不同的functionityproperties。
例如 A Car
和a Bike
同根同源 Vihicle
担子但是,a Bike
扩展了 Vihicle
鞍前马后 Car
例如,用电机来扩展车辆。因此,它们不能相互 "铸造",但两者都可以被看作是一个整体。Vihicle
.
有一些有用的扩展方法,可以处理类型检查。
foreach(Circle circle in shapes.OfType<Circle>())
{
// only shapes of type Circle are iterated.
}
"真实世界 "的例子:
如果你有一个Window,上面有很多控件。比如LabelsButtonsListViewsetc。所有这些控件都存储在其基础类型的集合中。
例如WPF控件。所有的子控件 (在FrameWorkElement中) 储存在 UIElementCollection
. 所以所有的控件都被添加为子控件 必须 得自 UIElement
.
当你在迭代所有的子控件时。(UIElement's) 并搜索一个标签,你必须检查它的类型。
foreach(UIElement element in this.Children)
{
if(element is Label)
{
Label myLabel = (Label)element;
myLabel.Content = "Hi there!";
}
}
这个循环将改变所有标签 (在此范围内) 到'你好!'。