您的位置:首页 > 编程语言 > C#

《csharp高级编程》 学习笔记 第四章 继承

2011-10-05 20:19 225 查看
第四章 继承

4.1 继承的类型

4.1.1 实现继承和接口继承

● 实现继承:表示一个类型派生于一个基类型,拥有该基类型的所有成员字段和函数。

● 接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。

接口继承常被看做一种契约:

让类型派生于接口,来保证为客户提供某个功能。

4.1.2 多重继承

csharp不支持多重实现继承。

但同时又允许类型派生于多个接口。

4.1.3 结构和类

结构不支持实现继承,但支持接口继承。

4.2 实现继承

public class MyDerivedClass : MyBaseClass, IInterface1,

IInterface2

{

//etc.

}

*csharp不支持私有继承,因此基类名上并没用public或private限定符。

*csharp支持object关键字,它用作System.Object类的假名。

4.2.1 虚方法

把基类函数声明为virtual,该函数就可以在派生类中重写。

class MyBaseClass

{

public virtual string VirtualMethod()

{

return "This method is virtual and defined in MyBaseClass";

}

}

也可以声明属性为virtual。

public virtual string ForeName

{

get { return foreName; }

set { foreName = value; }

}

private string foreName;

以下的讨论虽然都是对方法来说,但是也适用于属性。

*成员字段和静态函数都不能声明为virtual,因为这个概念只对类中的实例函数成员有意义。

4.2.2 隐藏方法

即c++中派生类和基类函数名相同时,且他们都没用声明virtual和override,则会同名覆盖。

但是在c#中,应该在派生类中对该新的重写函数添加关键字new前缀。

否则编译器会发出一个警告。

4.2.3 调用函数的基类版本

csharp的一个特殊语法可以用于从派生类中调用方法的基类版本:

base.function();

*这个语法可以调用基类中的任何方法。

4.2.4 抽象类和抽象函数

(类似c++的纯虚函数)

关键字abstract

c++开发人员要注意csharp中的一些语法区别。

csharp不能采用=0语法来声明抽象函数。

在csharp中,这个=<value>语法可以在类声明的成员字段上使用,提供初始值。

4.2.5 密封类和密封方法

关键字sealed

表示不能继承该类或该方法。

.NET基类库大量使用密封类。比如string。

4.2.6 派生类的构造函数

构造函数的调用顺序是先调用System.Object,

再按照层次结构由上向下进行,直到到达编译器要实例化的类为止。

*因为基类的构造函数总是最先调用。

故派生类的构造函数可以在执行过程中调用基类的成员,因为基类已经构造出来了。

public abstract class GenericCustomer

{

private string name;

public GenericCustomer()

: base() // we could omit this line without affecting the compiled code

{

name = "<no name>";

}

注意基类构造函数的调用base()

如果没加这个调用,编译器则在起始花括号的前面找不到对另一个构造函数的任何调用,

它会假定我们要调用基类构造函数。

这符号默认构造函数的工作方式。

*base和this关键字是调用另一个构造函数时允许使用的唯一关键字。

*还要注意只能制定一个其他的构造函数。

其它规则其实都和c++差不多。

都是定义派生类的同时要注意对基类构造函数的调用。

心细即可,原理不难。

4.3 修饰符

4.3.1 可见性修饰符

public。

private。

protected。

internal:只能在包含它的程序集中访问该方法。

4.3.2 其他修饰符

*注意一个extern,应用于仅静态[DllImport]方法。

说明成员在外部用另一种语言实现。

4.4 接口

下面是microsoft预定义的一个接口System.IDisposable的完整定义:

public interface IDisposable

{

void Dispose();

}

可看出,声明接口在语法上合声明抽象类完全相同。

但不允许提供接口中任何成员的执行方式。

接口不能有构造函数或字段。

接口定义也不允许包含运算符重载。

因为接口通常是公共契约,包含运算符重载会引起一些与其他.NET语言不兼容的问题。

接口成员总是公共的,不能声明为虚拟或静态。

如果需要最好通过执行的类来声明访问修饰符,像上例中的public。

接口的另一个例子是foreach循环。

foreach循环的内部工作方式是查询对象,看看它是否实现了System.Collections.IEnumerable 接口。

4.4.1 定义和实现接口

注意接口的名称传统上已字幕I开头(interface)。

namespace Wrox.ProCSharp

{

public interface IBankAccount

{

void PayIn(decimal amount);

bool Withdraw(decimal amount);

decimal Balance

{

get;

}

}

}

*接口引用完全可以看做是类引用--但接口引用的强大之处在于,它可以引用任何实现该接口的类。

IBankAccount[] accounts = new IBankAccount[2];

accounts[0] = new SaverAccount();

accounts[1] = new GoldAccount();

4.4.2 派生的接口

接口可以彼此继承,方式与类的继承相同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: