C#面向对象编程的3个支柱(二)

 

OOP第二个支柱:继承

继承是OOP的一个方面,可以促使代码重用。代码重用归为两类:经典继承(is-a关系)和包含/委托模型(has-a关系)。

当在类之间创建is-a关系时,也就是在两个或两个以上类类型之间创建依赖关系。经典继承是新的类(继承类)扩展既有类(基类/父类)的功能。基类的作用是为扩展类定义所以公共的数据与成员。

说起基类要清楚一点,.NET要求一个类只能有一个直接基类。我们不能创建派生自两个及两个以上基类的类类型。但.NET允许一个类型实现许多独立的接口,这样,可以实现很多行为,同事又避免了多重继承引起的复杂性。

//错误!.NET不允许继承多个类
class MyClass:BaseClassOne,BaseClassTwo
{
//...
}

sealed关键字

C#提供了sealed关键字来防止发生继承。如果使用sealed修饰一个类,那么就不允许我们从这个类型派生新的类型。

sealed class MyFinalClass:MyBaseClass
{}
//错误,不能扩展有sealed修饰的类
class MyClass:MyFinalClas
{}

通常,密封一个工具类是很有意义的。System命名空间定义了很多密封的工具类,有兴趣的去证实一下吧。

base关键字

class Person
{
public Person(){}
public Person(int age,String name)
{
this.Age=age;
this.Name=name;
}
publicint Age
{
set;
get;
}
public String Name
{
set;
get;
}
}

class Manager:Person
{
public String EmpNo
{
get;
set;
}
public Manager(){}
//用base调用适合的基类的构造函数,访问2次(1次基类构造函数,1次自定义函数)
public Manager(int age,string name,string empNo):base(age,name)
{
this.EmpNo=empNo;
}
}

base关键字挂接构造函数签名(和使用this关键字在单个类中串接构造函数的方法相似),这代表派生构造函数将数据传递到最近的父构造函数中,这这里,我们显式调用由Person定义的2个参数的构造函数,从而节省子类创建过程中的不必要调用。

//不使用base的情况
public Manager(int age,string name,string empNo)
{
this.EmpNo=empNo;
//基类继承的,在C#下,一般基类的默认构造函数先于派生类构造函数执行前被自动调用。
//之后,回访问Person基类的属性来创建其状态。
//创建Manager对象时访问4次(1次基类构造函数,1次自定义函数,2次属性赋值)!
this.Name=name;
this.Age=age;
}

protected关键字

作用:派生类不再需要使用基类的公共属性或公共方法间接访问数据了,当然坏处就是:如果派生类有权直接访问基类的数据,有可能偶尔绕过公共属性内设置的业务规则。

PS:对对象用户来说,受保护数据可以认为是私有的(因为用户是家族之外的)

 

被sealed修饰的类不能被继承,那么怎么才能重用该类的功能呢?答案就是使用包含/委托模型啦!

包含/委托模型

1、包含类中包含另一个对象(增加成员到包含类,以便使用被包含对象的功能)

class A
{
public int P{get;set;}
}
class B
{
public A a=new A();
}

2、嵌套类型定义

在C#中我们可以在类或结构结构中定义类型(枚举、类、接口、结构、委托)。被嵌套的类就是外部类的成员。

class A
{
public class B
{
public int P{get;set;}
}
}

ps:被嵌套类可以访问外部类的私有成员

posted @ 2011-07-08 12:55 黄宝强 阅读(...) 评论(...) 编辑 收藏