zoukankan      html  css  js  c++  java
  • C#学习笔记(二):继承、接口和抽象类

    继承

    密封类

    密封类(关键字sealed)是不允许其它类继承的,类似Java中的final关键字。

    1 public sealed class SealedClassName
    2 {
    3     //...
    4 }

    初始化顺序

    子类初始化顺序如下:

    1. 初始化类的实例字段;
    2. 调用基类的构造函数;
    3. 调用子类的构造函数。
     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             new C();
    10 
    11             Console.ReadKey();
    12         }
    13     }
    14 
    15     public class A
    16     {
    17         public A()
    18         {
    19             Console.WriteLine("A 类构造函数被调用。");
    20         }
    21     }
    22 
    23     public class B : A
    24     {
    25         public B()
    26         {
    27             Console.WriteLine("B 类构造函数被调用。");
    28         }
    29     }
    30 
    31     public class C : B
    32     {
    33         public C()
    34         {
    35             Console.WriteLine("C 类构造函数被调用。");
    36         }
    37     }
    38 }

    结果如下:

    1 A 类构造函数被调用。
    2 B 类构造函数被调用。
    3 C 类构造函数被调用。

    带参数的构造函数

    Java中使用super调用父类的构造函数,而C#中则使用base,同时写法也稍微有点不同,如下:

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             new C();
    10 
    11             Console.ReadKey();
    12         }
    13     }
    14 
    15     public class A
    16     {
    17         public A(int a, int b)
    18         {
    19             Console.WriteLine("A 类构造函数被调用。");
    20             Console.WriteLine(a + ":" + b);
    21         }
    22     }
    23 
    24     public class B : A
    25     {
    26         public B(int name1, int name2) : base(name1, name2)
    27         {
    28             Console.WriteLine("B 类构造函数被调用。");
    29         }
    30     }
    31 
    32     public class C : B
    33     {
    34         public C() : base(50, 100)
    35         {
    36             Console.WriteLine("C 类构造函数被调用。");
    37         }
    38     }
    39 }

    输出如下:

    1 A 类构造函数被调用。
    2 50:100
    3 B 类构造函数被调用。
    4 C 类构造函数被调用。

    方法多态

    子类重写父类的方法使用virtual和override实现。

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             new C().func();
    10 
    11             Console.ReadKey();
    12         }
    13     }
    14 
    15     public class A
    16     {
    17         public virtual void func()
    18         {
    19             Console.WriteLine("A 类的 func 方法调用。");
    20         }
    21     }
    22 
    23     public class B : A
    24     {
    25         public override void func()
    26         {
    27             Console.WriteLine("B 类的 func 方法调用。");
    28         }
    29     }
    30 
    31     public class C : B
    32     {
    33         public override void func()
    34         {
    35             base.func();
    36             Console.WriteLine("C 类的 func 方法调用。");
    37         }
    38     }
    39 }

    输出如下:

    1 B 类的 func 方法调用。
    2 C 类的 func 方法调用。

    阻止重写方法

    如果不希望虚方法被重写,可以使用sealed关键字。

    1 public sealed override void func()
    2 {
    3     //...
    4 }

    新成员方法隐藏老成员方法

    使用new关键字可以隐藏非虚的老成员方法。

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             C c = new C();
    10             c.func();
    11             ((B)c).func();
    12             ((A)c).func();
    13 
    14             Console.ReadKey();
    15         }
    16     }
    17 
    18     public class A
    19     {
    20         public void func()
    21         {
    22             Console.WriteLine("A 类的 func 方法调用。");
    23         }
    24     }
    25 
    26     public class B : A
    27     {
    28         public new void func()
    29         {
    30             Console.WriteLine("B 类的 func 方法调用。");
    31         }
    32     }
    33 
    34     public class C : B
    35     {
    36         public new void func()
    37         {
    38             Console.WriteLine("C 类的 func 方法调用。");
    39         }
    40     }
    41 }

    输出如下:

    1 C 类的 func 方法调用。
    2 B 类的 func 方法调用。
    3 A 类的 func 方法调用。

    接口

    C#中不允许多重继承,但接口可以多重继承。

    接口声明

    声明一个接口的写法如下:

    1 public interface ICustom
    2 {
    3 }

    C#中接口规则:

    1. 定义的方法不需要添加public等限定符,默认的所有方法都是public的;
    2. 可以包含方法、属性、事件和索引器;
    3. 不可以包含字段、运算符重载、构造函数和析构函数;
    4. 也不可以包含静态相关的所有定义;

    类实现接口

    实现接口的写法与继承一致:

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             ICustom custom = new Custom();
    10             custom.name = "A";
    11             custom.MoveTo(200, 100);
    12 
    13             Console.ReadKey();
    14         }
    15     }
    16 
    17     public interface ICustom
    18     {
    19         string name { set; get; }
    20 
    21         void MoveTo(float x, float y);
    22     }
    23 
    24     public class Custom : ICustom
    25     {
    26         public string name { get; set; }
    27 
    28         public void MoveTo(float x, float y)
    29         {
    30             Console.WriteLine("Custom "" + name + "" move to: " + x + ", " + y);
    31         }
    32     }
    33 }

    输出如下:

    Custom "A" move to: 200, 100

    接口的隐式实现和显式实现

    如果在实现接口时没有指明该方法是属于哪个接口的话,称为隐式实现,如上面的例子。如果指明了方法是来自哪个接口则称为显式实现。

    C#中的隐式实现与Java和AS3的使用一致,就不多讲,下面主要说一下接口的显式实现。

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             Custom custom = new Custom();
    10             custom.name = "A";
    11             (custom as ICustomA).MoveTo(200, 100);
    12             (custom as ICustomB).MoveTo(200, 100);
    13 
    14             Console.ReadKey();
    15         }
    16     }
    17 
    18     public interface ICustomA
    19     {
    20         string name { set; get; }
    21 
    22         void MoveTo(float x, float y);
    23     }
    24 
    25     public interface ICustomB
    26     {
    27         string name { set; get; }
    28 
    29         void MoveTo(float x, float y);
    30     }
    31 
    32     public class Custom : ICustomA, ICustomB
    33     {
    34         public string name { get; set; }
    35 
    36         void ICustomA.MoveTo(float x, float y)
    37         {
    38             Console.WriteLine("ICustomA "" + name + "" move to: " + x + ", " + y);
    39         }
    40 
    41         void ICustomB.MoveTo(float x, float y)
    42         {
    43             Console.WriteLine("ICustomB "" + name + "" move to: " + x + ", " + y);
    44         }
    45     }
    46 }

    运行结果如下:

    1 ICustomA "A" move to: 200, 100
    2 ICustomB "A" move to: 200, 100

    显示接口总结:

    1. 显示接口一般用于多个接口实现时,存在同名方法但需要不同的处理时。
    2. 我们发现如果使用显示的接口,需要将对象转换为对应的接口对象才能调用到对应的接口方法。
    3. 显示实现接口时不能写public在前方。
    4. 显示实现的接口不能由类直接访问,必须转换为对应的接口对象才行。

    抽象类

    C#中,抽象类使用与Java中一致,我们写一个例子来验证即可。

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             Custom custom = new Custom();
    10             custom.name = "A";
    11             custom.MoveTo(200, 100);
    12 
    13             Console.ReadKey();
    14         }
    15     }
    16 
    17     public abstract class AbstractCustom
    18     {
    19         public string name { set; get; }
    20 
    21         public abstract void MoveTo(float x, float y);
    22     }
    23 
    24     public class Custom : AbstractCustom
    25     {
    26         public override void MoveTo(float x, float y)
    27         {
    28             Console.WriteLine("Custom "" + name + "" move to: " + x + ", " + y);
    29         }
    30     }
    31 }

    运行结果如下:

    Custom "A" move to: 200, 100

    抽象类总结:

    1. 抽象类也是类,所以不能多重继承;
    2. 抽象类不能实例化,可以包含抽象方法,抽象方法不能实现;
    3. 抽象方法为虚方法;
    4. 非抽象子类必须实现抽象方法;
  • 相关阅读:
    apache2三种模式及切换到event模式
    MySQL添加用户、创建数据库、分配权限
    ExcelHelper导出
    C#中将错误写进日志文件
    k3 cloud金蝶云参数设置云之家集成,提示无法推送企业消息
    k3 cloud中用视图类型来展示数据
    k3 cloud python 插件实现点击对应的单据编号打开单据
    k3 cloud单据转换的表
    sql server查询某个表对应的触发器
    QPainter::begin: Paint device returned engine == 0, type: 3
  • 原文地址:https://www.cnblogs.com/hammerc/p/4598432.html
Copyright © 2011-2022 走看看