当前位置:首页 > C#类讲义
我们将于第12章全面讨论垃圾收集器与析构函数。 析构函数可以被以下修饰符修饰: 未托管代码修饰符 unsafe
3.1.12 部分类和方法
// PaymentFormGen.cs - auto-generated partial class PaymentForm { ... }
// PaymentForm.cs - hand-authored partial class PaymentForm { ... }
每一个分部都必须声明为partial;下面的例子是不合法的: partial class PaymentForm {} class PaymentForm {}
分部之间不能有成员冲突。例如,具有相同参数的构造函数不能在多个分部重复出现。所有的部分类,最后都由编译器装配成一个完整的类,这意味着每一个分部在编译时都必须是合法的并且存在于相同的汇编之中。
有两个办法给部分类指定基类:
在每一个分部中指定相同的基类。例如:
partial class PaymentForm : ModalForm {} partial class PaymentForm : ModalForm {}
仅为其中一个分部指定基类。例如:
partial class PaymentForm : ModalForm {} partial class PaymentForm {}
基类一般用于继承,我们将在即将到来的部分描述它。
3.1.12.1 部分方法(C# 3.0)
部分类可以包含部分方法。这似的自动产生的部分类能为手动编写方法实现提供定制钩子。例如:
// PaymentFormGen.cs - auto-generated partial class PaymentForm { ...
partial void ValidatePayment(decimal amount); }
// PaymentForm.cs - hand-authored partial class PaymentForm
{ ...
partial void ValidatePayment(decimal amount) {
if (amount > 100) ... } }
部分方法由两部分组成:定义和实现。定义通常是由代码产生器完成的,实现通常是手工键入的。如果没有提供具体实现,部分方法的定义就被编译器忽略了。这样使得自动产生的代码可以自由的提供钩子,而不用担心产生冗余代码。部分方法必须是void类型并且是隐式私有的。
3.2. 继承 一个类可以继承自另外一个类,以扩展或者定制最初的类。从一个现有的类继承可以重用这个类的功能而不用一切从基础做起。一个类只能继承一个类,但是它可以被多个类继承,从而构成了一个类的层次结构。在这个例子中,我们开始于丁仪一个名为Asset的类:
public class Asset {
public string Name;
public decimal PurchasePrice, CurrentPrice; } 下一步,我们定义两个类分别名为Stock和House,他们继承自Asset。Stock和House继承了Asset拥有的所有家当,并另外增加他们自己定义的成员:
public class Stock : Asset // inherits from Asset {
public long SharesOwned; }
public class House : Asset // inherits from Asset {
public decimal Mortgage; }
class Test {
static void Main( ) {
Stock msft = new Stock( ) { Name=\PurchasePrice=20, CurrentPrice=30, SharesOwned=1000 };
House mansion = new House
{ Name=\PurchasePrice=300000, CurrentPrice=200000,
Mortgage=250000 };
Console.WriteLine (msft.Name); // MSFT
Console.WriteLine (mansion.Name); // McMansion Console.WriteLine (msft.SharesOwned); // 1000 Console.WriteLine (mansion.Mortgage); // 250000 } }
子类Stock和House,从基类Asset继承了三个属性。 一个子类也被称作派生类 一个基类也被称为超级类
3.2.1. 多态
引用是多态的。这意味着基类的引用可以指向子类的实例。在接下来的例子中,有一个方法可以作用来显示Asset。它也可以被用来显示Stock和House,因为他们都是Assets:
class Test {
static void Main( ) {
Stock msft = new Stock ... ; House mansion = new House ... ; Display (msft); Display (mansion); }
public static void Display (Asset asset) {
System.Console.WriteLine (asset.Name); } } 多态工作的基本原理是,子类(Stock和House)拥有基类(Asset)的所有特征。然而,反过来表述的话就是不正确的。如果Display被修改为接受House类型的参数,你不能把一个Asset类型传递给它:
static void Main() { Display (new Asset( )); } // Compile-time error
public static void Display (House house) // Will not accept Asset
{
System.Console.WriteLine (house.Mortgage);
}
3.2.2. 转换
对象引用可以被:
? ?
隐式向上转换为基类引用 显式向下转换为子类引用
3.2.2.1. 向上转换
向上转换操作实质上就是从子类引用创建了一个基类引用。例如: Stock msft = new Stock(...);
Asset a = msft; // upcast
向上转换发生后,变量a与变量msft引用了相同的Stock对象。 对象只是被引用,而不是其本身被改变或者转化:
Console.WriteLine (a == msft); // true
虽然a和msft指向同一个对象,但是a看对象的视角更狭窄: Console.WriteLine (a.Name); // ok
Console.WriteLine (a.SharesOwned); // error: SharesOwned undefined
最后一行产生了一个编译期错误,因为引用a是Asset类型,即使它指向一个Stock对象。为了接触到它的SharedOwned成员域,必须将Asset向下转化为Stock。
3.2.2.2. 向下转换
向下装换动作从基类引用产生了子类引用。例如: Stock msft = new Stock( );
Asset a = msft; // upcast Stock s = (Stock)a; // downcast
Console.WriteLine (s.SharesOwned); //
向上转换只能影响引用而无法影响底层的对象。向下转换需要显式的转换,因为有可能会导致运行时失败:
House h = new House( );
Asset a = h; // Upcast always succeeds
共分享92篇相关文档