【C#与.NET程序设计】(5)- C#OOP

继承

继承可以促进代码重用。
代码重用归为两类:经典继承(“is-a”)、包含/委托继承(”has-a”)

经典继承

// 经典继承使用“:”标记继承关系
// 继承类拥有父类每个公共成员的访问权限
class car
{}

class miniCar : car
{}
  • .NET平台不允许类的多重继承(C/C++支持)
// 错误!不允许类的多重继承
class WontWork:BaseClassOne, BaseClassTwo
{}
  • 可以使用 sealed 关键字来防止发生继承
sealed class minCar:Car
{}

// 错误,不能派生
class deluxeMinCar:minCar
{}
  • 使用 base 关键字控制基类创建
class Employee
{
    //字段数据
    private string empName;
    private int empID;
    private float currPay;
    private int empAge;

    //自动属性
    public string Name{get; set;}
    public int Age{get; set;}
    public int ID{get; set;}
    public float Pay{get; set;}

    //构造函数
    public Employee(string name, int age, int id, float pay)
    {
        Name = name;
        Age = age;
        ID = id;
        Pay = pay;
    }
}

class Manager:Employee
{
    public int StockOptions{get; set;}

    //拥有6个输入的构造函数
    public Manager(string fullName, int age, int empID, float currPay, \
                   string ssn, int numbOfOpts)
    {
        // 如果在这里初始化所有变量会有两个问题
        // 1. 基类 Employee 非 public 的变量无法赋值
        // 2. 非常低效,因为默认会先调用基类构造函数,然后再重复访问赋值
    }

    //使用 base 
    //有点像参数列表,先初始化基类构造函数
    public Manager(string fullName, int age, int empID, float currPay, \
                   string ssn, int numbOfOpts):base(fullName, age, empID, currPay, ssn)
    {}
}

包含/委托继承

简单来说,就是一个类包含另一个类

// 包含/委托
class Employee
{
    // 包含一个 BenefitPackage 类的对象
    protected BenefitPackage empBenfits = new BenefitPackage();

    // 创建方法来使用其内部功能
    public double GetBenefiCost()
    {}

    // 通过自定义属性公开对象
    public BenefitPackage Benefits
    {
        get{return empBenfits;}
        set{empBenfits = value;}
    }
}

还有一种包含/委托的方式:嵌套类型

// 嵌套类型
public class OuterClass
{
    // 公共嵌套类型
    public class PublicInnerClass{}

    // 私有嵌套类型
    private class PrivateInnerClass{}
}
  • 嵌套类型可以完全控制内部类型的访问级别(非嵌套类型不能用 private,protected)
  • 由于嵌套类型是包含类(OuterClass)的成员,因此可以访问包含类私有成员

多态

简单说,就是子类对父类的方法重写

虚函数 virtual

// 多态
class Shape
{
    // 使用 virtual 定义一个虚方法
    public virtual void Draw()
    {
        Console.WriteLine("Inside Shape.Draw()");
    }
}

class Circle:Shape
{
    // 子类可以不实现父类的虚函数
    // 其对象直接调用父类虚函数
}

class Hexagon:Shape
{
    // 子类使用 override 重写虚方法
    public override void Draw()
    {
        Console.WriteLine("Drawing the Hexagon");
    }
}

抽象类 abstract

// 抽象类
// 抽象类里才可以定义抽象方法
abstract class Shape
{
    // 与虚方法的不同是,抽象方法没有具体实现
    // 但规定所有子类必须实现该函数
    public abstract void Draw();

}

class Circle:Shape
{
    // 子类使用 override 重写抽象方法
    public override void Draw()
    {
        Console.WriteLine("Drawing the Circle");
    }
}

成员投影

有时候对第三方父类做派生,需要重写函数,但父类相应的函数没有定义为虚函数或抽象函数
可以用 new 关键字隐藏父类版本

// 成员投影
// 父类
class Circle
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Circle");
    }
}

// 派生类,需要重写Draw
class ThreeCircle:Circle
{
    public new void Draw()
    {
        Console.WriteLine("Drawing a 3D Circle");
    }
}

// 调用 ThreeCircle 的 Draw()
ThreeCircle o = new ThreeCircle();
o.Draw();

// 也可以使用显式强制转换调用基类实现
((Circle)o).Draw();

基类与派生类的转换

  • 派生类可以隐式转换为父类
// 派生类 -> 父类
// 所有东西都是 object 的派生类
object frank = new Manager();
  • 父类可以显示转换为派生类
// 父类 -> 派生类
(Manager)frank
  • 使用“is”或“as”判断转换是不是有效
// 使用 is 关键字判断是不是指定的派生类
if(frank is Manager)
{...}

// 使用 as 关键字判断转换是不是有效
Manager man = frank as Manager;
if(man == null)
    Console.WriteLine("frank is not a Manager");

参考

【1】C#与.NET 4高级程序设计(第5版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值