概述:C# 单继承,可以实现多个接口。派生层次的最终基类为System.Object
。
零 继承
0.继承类型概述
- 实现继承: 表示一个类型派生于一个基类型,它拥有该基类型的虽有成员字段和函数。
- 接口继承: 表示一个类型只能计策函数签名,没有继承实现任何代码。
- 多重继承: 多重继承:一个类派生自多个类。
1.C#中的继承特点
- 结构总数派生自
System.ValueType
,他们还可以派生任意多个接口。 - 类总是派生自另一个类,他们还可以派生自任意多个接口。
- 备注 结构不支持实现继承,但支持接口继承。
一 C#实现继承
0.语法
- 关键字
object
代表Object
类。
//对于类
public class MyClass:BaseClass,IMyInterface01,IMyInterface02
{
//etc
}
public struct MyStruct:IMyInterface01,IMyInterface02
{
//etc
}
1.虚方法(虚属性)
- 把一个基类函数声明为
virtual
,就可以在任何派生类中重写该函数。 - 可以在派生类中重写虚函数,需要显式加上
overvide
关键字。(只有基类方法是虚拟的,才能在派生类中使用override
关键字;非虚方法不能使用该关键字。) - C# 默认是非虚方法
class A
{
public virtual void Method()
=>Console.WriteLine("A");
public void Method02()
=>Console.WriteLine("Method02 A");
}
class B : A
{
//重写基类虚方法
public override void Method()
=>Console.WriteLine("B");
//无法重写基类的非虚方法
//public override void Method02()
// =>Console.WriteLine("Method02 B");
}
class C:A
{
//也可以不重写基类的虚方法
}
2.new方法(隐藏方法)
- 如果派生类中声明与基类签名相同的方法,但是该方法没有声明分别声明为
virtual
与override
,派生类会隐藏基类的方法。 - 显式隐藏与隐式隐藏,取决于当在派生类中声明同样签名方法时候有没有使用new关键字。
- 除非隐藏了父类方法,不然父类方法的修饰符
virtual
sealed
,会被派生类继承。
class A
{
public void Method()
=> Console.WriteLine("A");
}
class B : A
{
//显示隐藏,new 关键字最好放在前面,表示这个显示隐藏了一个基类方法
new public void Method()
=> Console.WriteLine("B");
//隐式隐藏,编译会警告
//new public void Method()
//=>Console.WriteLine("B");
}
- 有个比较特殊的情况:如果基类是虚方法,派生类没有用override关键字,那么这种情况其实是,派生类隐式隐藏了基类的方法。
class A
{
public virtual void Method()
=> Console.WriteLine("A");
}
class B : A
{
//其实是隐式隐藏
public void Method()
=> Console.WriteLine("B");
}
class C : B
{
//这个是不允许的,因为隐藏父类方法后,相当于是重新定义了一个方法,
//所以 B中的Method是新的方法,是非虚的方法,所以不能用override
//public override void Method()
// =>Console.WriteLine("B");
}
3.sealed方法
- 方法和属性会加上
sealed
会禁止派生类重写该方法。 sealed
不能添加到非虚方法。- 基类方法是
sealed
,派生类不可以重写该方法;但是派生类可以隐藏基类的方法,然后在指定为virtual
,那么该派生类的派生类就可以重写方法了。
class A
{
public virtual void Method()
=> Console.WriteLine("A");
//无法非虚方法使用sealed
//public sealed void Method02()
// => Console.WriteLine("Method02 A");
}
class B : A
{
public override sealed void Method()
=> Console.WriteLine("B");
}
class C : B
{
//无法对基类的sealed方法重写
//public override void Method()
// => Console.WriteLine("B1");
//这里是先把基类的方法显式隐藏了
//然后在把Method定义为虚方法,B1的派生类就可以重写Method
new public virtual void Method()
=> Console.WriteLine("B1");
}
class D : C
{
//这里重写的是C中的Method方法
public override void Method()
=> Console.WriteLine("B1");
}
4.base
- 在继承中,如果需要调用基类的成员,可以使用base来表示基类对象。
class A
{
public virtual void Method()
=> Console.WriteLine("A");
//无法非虚方法使用sealed
//public sealed void Method02()
// => Console.WriteLine("Method02 A");
}
class B : A
{
public override sealed void Method()
=> base.Method();
}
二.接口
0.接口定义
- 接口不允许提供任何接口成员的实现
- 接口不能有构造函数,也不能有字段。
- 接口成员包括方法、属性、索引器和事件的声明。
- 接口成员总是公有的,不能声明为虚拟或者静态的。
- 接口的命名前面加一个
I
。
interface IMyA01
{
void Method();
int Age { get; }
decimal Birthday { get; set; }
}
1.接口的派生
- 接口可以派生自多个接口
- 类可以实现多个接口
interface IMyA01
{}
interface IMyA02
{}
interface IMyB:IMyA01,IMyA02
{}
class MyClass : IMyA01, IMyA02
{ }