C#学习之继承

版权声明:未经作者允许不可转载 https://blog.csdn.net/qq_38134452/article/details/80546928
  • 基本概念
    • 面向对象的三个特性:继承、封装、多态

继承

  • 继承的类型:单重继承、多重继承、多层继承(C#不支持类的多重继承,但允接口的多重继承)、接口继承
  • 实现继承

    //类
    class child : MyBaseClass
    class child : MyBaseClass,Interface1,Interface2
    //接口(只能用于继承接口)
    public struct childStruct : Interface
  • 虚方法:把一个基类声明为virtual,就可以在任何派生类中重写该方法

    public class Shape
    {
      public virtual void Draw()
      {
          WriteLine($"xxxxxxx");
      }
    }

    如果实现代码只有一行,可以用lambda运算符一起使用。
    “`
    public class Shape
    {
    public virtual void Draw() => WriteLine($”xxxxxxx”);
    }

  • C#在派生类重写函数时,要使用override关键字显示声明。

    public class child : Shape
    {
      public override void Draw()=>
      WriteLine($"xxxxxxx");
    }

    成员字段和静态函数都不能声明为virtual,这个概念只有在类的实例函数才有意义

多态

  • 使用多态性,可以动态的定义调用的方法,而不是在编译期间定义。编译器创建一个虚拟方法表(vtable),其中列出了可以在运行期间调用的方法,它根据运行期间的类型调用方法。
  • 调用方法的基类版本

    public class Shape
    {
      public virtual void Move(Position newPosition)
      {
          WriteLine($"xxxxxxx");
      }
    }
    
    public class Rectangle : Shape
    {
      public override void Move(Position newPosition)
      {
          base.Move(newPosition);//调用了基类的方法
      }
    }
  • 抽象类和抽象方法:C#允许把类和方法声明为abstract。抽象类不能被实例化,而抽象方法不能直接实现,必须在非抽象的派生类中重写。显然,抽象方法本身也是虚拟的

    public abstract class Shape
    {
      public abstract void Resize(int width,int height);
    }
    
    public class Ellipse : Shape
    {
      public override void Resize(int width,int height)
      {
          Size.Width=width;
          Size.Height=heigth;
      }
    }

    使用抽象类Shape类和派生的Ellipse类,可以声明Shape的一个变量,但不能实例化。

    Shape s1=new Ellipse();

    DrawShape(s1);

  • 密封类和密封方法:给类添加sealed修饰符,就不允许创建该类的子类

    sealed class FinalClass
    {
    public sealed override void FinalMethod()
    {
        WriteLine($"xxxxxxx");
    }
    }

    之后再也不能扩展扩展这个方法的虚拟表

  • 派生类的构造函数

    public class Shape
    {
      public Shape()
      {
          Position=new Position();
          Size =new Size();
      }
    }
    
    public class Ellipse : Shape
    {
      public Ellipse() : base()//“继承”基类的构造方法
      {}
    }
  • 修饰符

    • 访问修饰符:
    修饰符 应用于 说明
    public 所有类型和成员 任何代码均可以访问该项
    protect 类型和内嵌类型的所有成员 只有派生的类型才能访问该项
    internal 所有类型和成员 只能在包含它的程序集中访问该项
    private 类型和内嵌类型的所有成员 只能在它的所属类型中访问该项
    protected internal 类型和内嵌类型的所有成员 只能在包含它的程序集和派生类型的任何代码中访问该项

    注意:internal是一个物理访问修饰符,其边界是一个程序集。其他是逻辑访问量

    • 其他修饰符
    修饰符 应用于 说明
    new 函数成员 成员用相同的签名隐藏继承的成员
    static 所有成员 成员不作用于类的具体事例,也称为类成员,而不是实例成员
    virtual 仅函数成员 成员可以由派生类重写
    abstract 仅函数成员 虚拟成员定义了成员的签名,但没有提供实现代码
    override 仅函数成员 成员重写继承的虚拟或抽象成员
    sealed 类、方法和属性 对于类,不能继承自密封类。对于属性和方法,成员重写已继承的虚拟成员,但任何派生类和派生成员都不能重写该成员。该修饰符必须与override一起使用
    extern 仅静态[DllImport]方法 成员在外部用另一种语言实现。(参见第五章)
  • 接口

    public interface IBankAccount
    {
      void PayIn();
      bool Withdraw()
    }
    
    public class SaveAccount : IBankAccount
    {
      void PayIn() => WriteLine($"xxxxxxx");
      bool writedraw() => return true;
    }

    编程的好习惯:通常用I开头表示接口

  • 派生的接口:与类的派生类似。

  • is 和 as 运算符

    • as

      Object o;
      IbankAccount account=(IBankAccount)o;
    • as的原理类似于类层次中的cast运算符——他返回对象的引用。如果对象不是所要求的类型,那么便返回空。(避免了类型转换)

      IBankAccount account = o as IBankAccount
      if(account != null)
      {
       //operation
      }
    • is

      Object o;
      if(o is IBankAccount)
      {
        //operate
      }

猜你喜欢

转载自blog.csdn.net/qq_38134452/article/details/80546928