继承

密封类

密封类(关键字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. 非抽象子类必须实现抽象方法;

C#学习笔记(二):继承、接口和抽象类的更多相关文章

  1. Java学习笔记之---比较接口与抽象类

    Java学习笔记之---比较接口与抽象类 抽象类是描述事物的本质,接口是描述事物的功能 接口与抽象类的异同 1.一个类只能继承一个父类,但是可以有多个接口 2.抽象类中的抽象方法没有方法体,但是可以有 ...

  2. java基础学习笔记二(接口、super、this)

    一.super 和 this的用法 主要解释一下引用构造函数的用法 super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句) this(参数):调用本类中另一种形式的构造函数(应 ...

  3. 【知了堂学习笔记】java 接口与抽象类

    本次主角:抽象类 .接口. 对于皮皮潇这样一类的Java初学者来说,接口和抽象类如果不去花大量的精力与时间是很难弄清楚的,而我也是在最近这周的项目学习中感觉到了我对这两个概念不熟悉,所以导致对一些问题 ...

  4. 吴裕雄--天生自然C++语言学习笔记:C++ 接口(抽象类)

    接口描述了类的行为和功能,而不需要完成类的特定实现. C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念. 如果类中至少有一个函数被声明为纯虚 ...

  5. PHP学习笔记二十八【抽象类】

    <?php //定义一个抽象类.主要用来被继承 //如果一个类继承了抽象类,则它必须实现该抽象类的所有抽象方法(除非它自己也是抽象类) // abstract class Animal{ pub ...

  6. mybatis学习笔记二(接口注解)

    直接上代码,全部在代码里讲解. 1.实体类 package com.home.entity; /** * 此类是:user实体类 * @author hpc * @2017年1月10日下午9:36:5 ...

  7. Java学习笔记二十八:Java中的接口

    Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...

  8. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. 学习笔记(二)--->《Java 8编程官方参考教程(第9版).pdf》:第七章到九章学习笔记

    注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法者自负一切 ...

  10. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

随机推荐

  1. mybatis源码分析(1)——SqlSessionFactory实例的产生过程

    在使用mybatis框架时,第一步就需要产生SqlSessionFactory类的实例(相当于是产生连接池),通过调用SqlSessionFactoryBuilder类的实例的build方法来完成.下 ...

  2. UVa 12230 (期望) Crossing Rivers

    题意: 从A到B两地相距D,之间有n段河,每段河有一条小船,船的位置以及方向随机分布,速度大小不变.每段河之间是陆地,而且在陆地上行走的速度为1.求从A到B的时间期望. 分析: 我们只要分析每段河的期 ...

  3. HDU 2594 (简单KMP) Simpsons’ Hidden Talents

    题意: 有两个字符串,找一个最长子串是的该串既是第一个字的前缀,又是第二个串的后缀. 分析: 把两个串并起来然后在中间加一个无关字符,求next数组即可. #include <cstdio> ...

  4. BZOJ_1629_[Usaco2007_Demo]_Cow_Acrobats_(贪心)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1629 \(n\)头牛叠罗汉.第\(i\)头牛的力量为\(s_i\),重量为\(w_i\),危险 ...

  5. UVALive 4287 Proving Equivalences(缩点)

    等价性问题,给出的样例为 a->b的形式,问要实现全部等价(即任意两个可以互相推出),至少要加多少个形如 a->b的条件. 容易想到用强连通缩点,把已经实现等价的子图缩掉,最后剩余DAG. ...

  6. php.ini配置中文详解

    ;;;;;;;;;;; ; 警告 ; ;;;;;;;;;;; ; 此配置文件是对于新安装的PHP的默认设置. ; 默认情况下,PHP使用此配置文件安装 ; 此配置针对开发目的,并且*不是*针对生产环境 ...

  7. #include<unistd.h>头文件的理解

    1.百度百科定义 unistd.h 是 C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称.该头文件由 POSIX.1 标准(单一UNIX规范的基础)提出,故 ...

  8. Nginx & AWStats 安装、配置、使用

    —— 参考IBM文章:THIS , 不一样的指导顺序 —— 1. awstats分析nginx - access.log,网上资料大部分都是下载,然后配置.官网下载地址: http://awstats ...

  9. zoj 2027 Travelling Fee

    // 题意 : 一个人要去旅行 给你起点和终点 求最少花费 其中花费为经过路径的总费用减去该路径的中的最大花费段// 直接搜索 稍微加了个剪枝 主要是数据规模小#include <iostrea ...

  10. Oracle 闪回特性(FLASHBACK DATABASE)

    --===================================== -- Oracle 闪回特性(FLASHBACK DATABASE) --======================= ...