C#学习笔记(二):继承、接口和抽象类

继承

密封类

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

 public sealed class SealedClassName
{
//...
}

初始化顺序

子类初始化顺序如下:

  1. 初始化类的实例字段;
  2. 调用基类的构造函数;
  3. 调用子类的构造函数。
 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
new C(); Console.ReadKey();
}
} public class A
{
public A()
{
Console.WriteLine("A 类构造函数被调用。");
}
} public class B : A
{
public B()
{
Console.WriteLine("B 类构造函数被调用。");
}
} public class C : B
{
public C()
{
Console.WriteLine("C 类构造函数被调用。");
}
}
}

结果如下:

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

带参数的构造函数

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

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
new C(); Console.ReadKey();
}
} public class A
{
public A(int a, int b)
{
Console.WriteLine("A 类构造函数被调用。");
Console.WriteLine(a + ":" + b);
}
} public class B : A
{
public B(int name1, int name2) : base(name1, name2)
{
Console.WriteLine("B 类构造函数被调用。");
}
} public class C : B
{
public C() : base(, )
{
Console.WriteLine("C 类构造函数被调用。");
}
}
}

输出如下:

 A 类构造函数被调用。
:
B 类构造函数被调用。
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 }

输出如下:

 B 类的 func 方法调用。
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 }

输出如下:

 C 类的 func 方法调用。
B 类的 func 方法调用。
A 类的 func 方法调用。

接口

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

接口声明

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

 public interface ICustom
{
}

C#中接口规则:

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

类实现接口

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

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
ICustom custom = new Custom();
custom.name = "A";
custom.MoveTo(, ); Console.ReadKey();
}
} public interface ICustom
{
string name { set; get; } void MoveTo(float x, float y);
} public class Custom : ICustom
{
public string name { get; set; } public void MoveTo(float x, float y)
{
Console.WriteLine("Custom \"" + name + "\" move to: " + x + ", " + y);
}
}
}

输出如下:

Custom "A" move to: , 

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

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

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

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
Custom custom = new Custom();
custom.name = "A";
(custom as ICustomA).MoveTo(, );
(custom as ICustomB).MoveTo(, ); Console.ReadKey();
}
} public interface ICustomA
{
string name { set; get; } void MoveTo(float x, float y);
} public interface ICustomB
{
string name { set; get; } void MoveTo(float x, float y);
} public class Custom : ICustomA, ICustomB
{
public string name { get; set; } void ICustomA.MoveTo(float x, float y)
{
Console.WriteLine("ICustomA \"" + name + "\" move to: " + x + ", " + y);
} void ICustomB.MoveTo(float x, float y)
{
Console.WriteLine("ICustomB \"" + name + "\" move to: " + x + ", " + y);
}
}
}

运行结果如下:

 ICustomA "A" move to: ,
ICustomB "A" move to: ,

显示接口总结:

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

抽象类

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

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
Custom custom = new Custom();
custom.name = "A";
custom.MoveTo(, ); Console.ReadKey();
}
} public abstract class AbstractCustom
{
public string name { set; get; } public abstract void MoveTo(float x, float y);
} public class Custom : AbstractCustom
{
public override void MoveTo(float x, float y)
{
Console.WriteLine("Custom \"" + name + "\" move to: " + x + ", " + y);
}
}
}

运行结果如下:

Custom "A" move to: , 

抽象类总结:

  1. 抽象类也是类,所以不能多重继承;
  2. 抽象类不能实例化,可以包含抽象方法,抽象方法不能实现;
  3. 抽象方法为虚方法;
  4. 非抽象子类必须实现抽象方法;
上一篇:11gR2数据库日志报错:Fatal NI connect error 12170、


下一篇:解决sublime text3 文件名,小框框的办法