MiCoos 哟,写bug呢?

C#基础 继承、接口

2019-09-03
GHMicoos

概述: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方法(隐藏方法)

  • 如果派生类中声明与基类签名相同的方法,但是该方法没有声明分别声明为virtualoverride,派生类会隐藏基类的方法。
  • 显式隐藏与隐式隐藏,取决于当在派生类中声明同样签名方法时候有没有使用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
{ }



Similar Posts

Comments