码迷,mamicode.com
首页 > Windows程序 > 详细

C#本质论6.0第六章:继承

时间:2018-10-23 01:16:00      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:调用   nta   tac   get   强制   sha   private   不可   lin   

基类型与派生类型之间的转型:

显式转型与隐式转型:

从派生类型转型为基类型称为隐式转型,转型总会成功,不会引发异常。

从基类型转型为派生类型称为显式转型,在转型过程中可能会失败,为了执行显示转型,要在原始引用名称之前,将要转换成的类型放在前面圆括号中。

自定义转换:

不相关的类型之间也能进行相互转换,C#允许类型包含显式与隐式转型转换符,在转型有可能失败时,开发者应定义显式转型操作符。

class GPSCoordinates
{
    //...
    public static implicit operator UTMCoordinates(
        GPSCoordinates coordinates)
    {
        //implicit 隐式转换关键字
        //explicit 显式转换关键字
    }
}

单继承:

一个类不能直接从两个类派生。

在极少数需要多继承结构的时候,一般的解决方案是使用聚合

  • 聚合:一个类包含另一个类的实例。
public class PdaItem
{
    //主要基类
}
public class Person
{
    //字段类
}
public class Contact : PdaItem
{   //派生类
    //持有另一个类的实例
    private Person InternalPerson{get; set;}
    public string FirstName
    {
        get{return InternalPerson.FirstName;}
        set{InternalPerson.FirstName = value;}
    }
    //...
}

缺点:

1. 因委托而增加复杂性。
?   2. 在字段类上新增的任何方法都需要人工添加到派生类中,否则Contact无法公开新增的功能。

密封类:

为了正确设计类,让其他人通过继承来拓展它的功能,需要对它进行全面测试,验证派生能成功的进行。为了避免非预期的派生,并避免出现因此而产生的问题,可以把类标记为sealed

public sealed class CommandLineParser
{
    //...不能从该类派生出其他类
}

基类的重写:

在基类中,必须将允许重写的每个成员标记为virtual,假如一个public或protected成员没有包含virtual修饰符,就不允许子类重写该成员。

public class PdaItem
{
    public virtual string Name{get;set;}
}

public class Contact : PdaItem
{
    public override string Name
    {
        //...
    }
}
  • 对成员进行重载,会造成运行时调用最深的或者说派生的最远的实现。因此,虚方法不应包含关键代码,如果派生类重写了它,那么那些代码将永远得不到调用。不要在构造器中调用会影响所构造对象的任何虚方法,假如这个虚方法在当前要实例化的类型的派生类型中进行了重写,就会调用重写的实现,但在继承层次结构中,字段尚未完全初始化,所以调用虚方法将导致无法预测的行为。
  • 如果没有对虚方法进行重写,编译器会报告警告信息,我们可以通过new关键字来解决该问题:
    • new修饰符在基类面前隐藏了派生类重新声明的成员,这时不是调用派生的最远的成员,相反,是搜索继承链,找到使用new修饰符的那个成员之前的成员,然后调用该成员。如果继承链中仅包含两个类,就会使用基类的成员,感觉就像是派生类没有重写那个成员。
  • 对类使用sealed修饰符可以禁止从该类继承,虚成员也可以密封。一般很少将整个类标记为密封,除非是遇到迫切需要这种限制的情况。
  • base成员:重写成员时,调用该成员的基类版本。
  • override修饰的任何成员都自动成为虚成员。

构造器:

在实例化一个派生类的时候,运行时首先调用基类的构造器,以避免绕过对基类的初始化。假如基类没有可访问的默认构造器,我们需要在派生类构造器的头部显式指定要运行哪一个基类构造器。

public class Contact : PdaItem
{
    public Contact(string name):base(name)
    {
        Name = name;
    }
}

抽象类:

(abstract)抽象类是仅供派生的类,无法实例化抽象类,只能实例化从它派生的类。抽象成员定义了从抽象实体派生的对象应包含什么,但这种成员不包含实现。一个类要从抽象类成功的派生,必须为抽象基类的抽象方法提供具体的实现。

  • 不可实例化只是抽象类的一个较次要的特征,其主要特征是它包含抽象成员,抽象成员是没有实现的方法或属性,其作用是强制所有派生类提供实现。

is&as

  • is操作符可以用来判断基础类型,并非仅仅是检查数据能否成功转型为目标类型,还会检查底层对象本身是否是目标类型,如果不是,返回false
  • as尝试将对象转换成特定数据类型,当不能转换的时候,as操作符会返回null。

C#本质论6.0第六章:继承

标签:调用   nta   tac   get   强制   sha   private   不可   lin   

原文地址:https://www.cnblogs.com/zhang-mo/p/9834062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!