六、继承
6.1 派生
6.1.1 自定义转换
不相关类型之间也能进行转换 可能转型失败或者进行有损转换时应定义显式转换操作符
6.1.1.1 隐式转换操作符
public static implicit operator TransTo( Class transFrom)
将transFrom隐式转换为TransTo TransTo A = transFrom
6.1.1.2 显式转换操作符
public static explicit operator
public class Person
{
public int id { get ; set ; }
public string name { get ; set ; }
public static explicit operator string ( Person person)
{
return $"id: { person. id } ,name: { person. name } " ;
}
}
public static void Main ( )
{
Person person = new Person
{
id = 1 ,
name = "Nicholas"
} ;
string personStr = ( string ) person;
}
6.1.2 protected
在基类和派生类中可访问受保护的成员,即使派生类不在同一程序集中 要从派生类中访问受保护成员,必须在编译时确定是从派生类(或者某个子类)的实例中访问受保护成员
对于从一个基类继承下来的两个兄弟类来说,在其中一个兄弟类中不应该能访问另一个兄弟类的受保护的成员 所以当接收一个基类型的变量时需要转化为派生类才能访问受保护成员。
6.1.3 聚合
C#是单继承 语言
解决单继承问题
从一个类派生,并将另一个类作为私有属性 若需要利用属性类中的成员及方法,需要重新声明,并在取值、赋值以及方法调用的实现中调用相应的属性类的成员及方法(委托) 若属性类中新增功能,而派生类也需要利用这些功能,则需要在派生类中再新增代码将功能公开。
public class PdaItem {
}
public class Person {
}
public class Contract : PdaItem {
private Person InternalPerson{ get ; set ; }
public string FirstName{
get { return InternalPerson. FirstName; }
set { InternalPerson. FirstName= value ; }
}
}
6.1.4 密封类
用sealed修饰,不能派生 sealed也可修饰虚成员,即禁止派生类继承该类重写的成员属性或方法
6.2 基类的重写
重写产生的原因
基类的某些实现对于基类来说是恰当的,但对于派生类来说,可能有个性化的需求,直接使用从基类继承下来的实现可能不太合适 重写的适用范围
“运行时”遇到虚方法时,会调用虚成员派生得最远的、重写的实现
6.2.1 virtual、override修饰符
基类中标记允许重写
使用virtual修饰才具备重写的能力 C#中默认所有都是非虚方法,即不能被派生类重写,而JAVA中默认都是虚方法 派生类中进行重写
应该使用override修饰 若派生类不用override修饰,则相当于定义了一个与基类完全无关,但与基类方法同名的方法,其该方法会将基类的同名方法屏蔽,默认被new修饰 重写后的方法也是virtual的
6.2.2 new 修饰符
在派生类中生成与基类无关但同名的方法
会将父类方法屏蔽 无论基类方法是否用virtual修饰 即使不使用new修饰符,默认也是new,但会出现警告
提醒是否是忘了添加override new的作用则是消除警告
6.2.3 base
相当于JAVA中的super关键字 可作为基类版本使用
可在构造器中使用 :base() 调用基类构造器
6.3 抽象类
6.3.1 抽象类的特点
抽象类的主要特征是包含抽象成员
方法被abstract修饰,派生类必须实现 该方法自动为虚方法,但不能用virtual修饰 抽象成员是没有实现的方法或属性 派生类实现也需要用override修饰 ,否则默认为new
6.3.2 多态性 ploymorphism
同一个签名可以有多个实现,该签名的每个实现包含在不同的类中 抽象成员是实现多态性的一个手段
对共有属性的一种提炼 相对于普通的类继承,抽象类的出现是基类在使用过程中永远不会进行实例化的特殊情况
6.4 System.Object
6.5 is、as操作符
is
判断原始类型,即创建时的类型 而不是判断是否可以进行类型转换
即便该类型自定义了相应的转型操作符也会返回false as