C#高级编程笔记 Day 3, 2016年9月 8日 抽象类

时间:2023-02-25 23:37:12

1、虚方法:把一个基类函数声明为 virtual,就可以在任何派生类中重写该函数。

2、在Java 中所有函数都是虚拟的,但是在C# 中,C# 要求在派生类的函数重写另一个函数时,要使用 override 关键字显式声明。

//父类
class MyBaseClass{
public virtual string VirtualMethod(){
return "This is test!";
}
} //派生类
class MyDerivedClass:MyBaseClass{
public override string VirtualMethod(){
return "Haha, I override you."
}
}

3、成员字段和静态函数都不能声明为 virtual ,因为这个概念只对类中的实例函数成员有意义。

4、隐藏方法:如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为 virtual 和 override ,派生类的方法就会隐藏基类方法。在大多数情况下,是要重写方法,而不是隐藏方法,因为隐藏方法会造成对于给定类的实例调用错误方法的危险。在c#中,要隐藏一个方法,应该使用 new 关键字声明。

class MyDerivedClass:MyBaseClass{
public new string VirtualMethod(){
//...
return ;
}
}

5、调用函数的基类版本 : base . <MethodName>()

class MyBaseClass{
public virtual string getName(){
return "Hello ,Robert!";
}
} class MySonClass : MyBaseClass{
public override string getName(){
return base.getName();
}
}

6、【专题】抽象类和抽象函数。(abstract)

  抽象类:

    • 抽象类不能被密封(sealed)。
    • 抽象类不能被实例化。
    • 如果类包含抽象函数,则该类也是抽象的。也必须声明为抽象的。

  抽象函数:

    • 抽象函数不能直接实现,必须在非抽象的派生类中重写。
    • 抽象函数本身也是虚拟的(尽管也不需要提供 virtual 关键字,实际上,如果提供了该关键字,就会产生一个语法错误。)不需要显式写出 virtual。

7、密封类和密封方法。 sealed

  对于类:表示不能继承该类。

  对于方法:表示不能重写该方法。

  string 为密封类。

  要在方法或属性上使用 sealed 关键字,必须先从基类上把它声明为要重写的方法或属性。如果基类上不希望有重写的方法或属性,就不要把它声明为 virtual。

8、【派生类中的构造函数执行过程】

abstract class GenericCustomer{
private string name;
} class NevermoreCustomer:GenericCustomer{
private uint highCostMinutesUsed;
} GenericCustomer customer=new NevermoreCustomer();

C#高级编程笔记 Day 3, 2016年9月 8日 抽象类

  【执行过程】:编译器首先找到它试图实例化的类的构造函数,在本例中是 NevermoreCustomer ,这个默认 NevermoreCustomer 构造函数首先要做的是为其直接基类 GenericCustomer 运行默认构造函数,然后GenericCustomer 构造函数为其直接基类System.Object 运行默认构造函数,System.Object 没有任何基类,所以它的构造函数就执行,并把控制权返回给GenericCustomer 构造函数,现在执行 GenericCustomer 构造函数, 把变量 name 初始化 为 null 。再把控制权返回给 NevermoreCustomer 构造函数, 接着执行这个构造函数, 把 highCostMinuteUsed 初始化为 0 并退出。

  构造函数的调用顺序是先调用 System.Object, 再按照层次结构由上向下进行。直到达到编译器要实例化的类为止。

9、this 和 base

  this 为调用当前类中的其他构造方法。

  base 在派生类中使用时,调用基类中的构造方法。

10、接口 。Microsoft 预定义的一个接口 System.IDisposable。 它包含一个方法 Dispose() ,该方法由类实现,用于清理代码。

 public interface Idisposable{
void Dispose();
}

  接口在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的实现方式。一般情况下,接口只能包含方法,属性,索引器和事件的声明。不能实例化接口,它只能包含其成员的签名。接口既不能有构造函数,也不能有字段。接口定义也不允许包含运算符重载,不允许声明关于成员的修饰符。接口成员总是共有的,不能声明为虚拟或静态。

11、【专题 C#中抽象类和接口的区别】

  Ⅰ、抽象类

    ① 抽象类是特殊的类,只是不能被实例化。除此之外,具有类的其他特性。

    ② 抽象类可以包含抽象方法,这是普通类所不能的。

    ③ 抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖他们。

    ④ 抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖他们。

  Ⅱ 、接口:为引用类型。类似于 类 ,在以下三点相似抽象类。

    ① 不能实例化。

    ② 包含未实现的方法声明。

    ③ 派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员。(不仅是方法,包括其他成员。)

  接口除了可以包含方法之外,还可以包含属性,索引器,事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他成员。

  一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)

  Ⅲ、抽象类和接口的区别

    ① 类是对“对象” 的抽象,把“抽象类”理解为“把类当作对象”抽象成的类叫做抽象类。接口则为行为规范或规定。

    ② 一个类一次可以实现若干个接口,但是只能扩展一个父类。

    ③ 接口可以用于支持回调,而继承并不具备这个特点。

    ④ 抽象类不能被密封。

    ⑤ 抽象类实现的具体方法默认为虚(virtual)的,但实现接口的类中的接口方法却默认为非虚的。

    ⑥ 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口中一个功能,而不得不去实现接口中的其他方法就叫接口污染。

    ⑦ 尽量避免使用继承来实现组件功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中的某一类,就必须把他们全部加载到栈中。

    ⑧ 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。

  Ⅳ、抽象类和接口的使用

    ① 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。

    ② 如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口。

    ③ 如果要设计大的功能单元,则使用抽象类,如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。

    ④ 抽象类主要用于关系密切的对象,而接口适合为不想关的类提供通用功能。

网上一个挺好的例子:

  飞机会飞,鸟会飞,它们都实现了同一个 接口 ”飞“,但 波音747 属于 飞机 抽象类,鸽子属于 鸟 抽象类

C#高级编程笔记 Day 3, 2016年9月 8日 抽象类的更多相关文章

  1. Android高级编程笔记(四)深入探讨Activity(转)

    在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ...

  2. 我的Python成长之路---第八天---Python基础(24)---2016年3月5日(晴)

    多线程编程 什么是多线程,线程是操作系统能够进行运算调度的最小单位.他包含在进程之中,是进程中的实际运作单位.线程是进程中一个单顺序的空值六,一个进程可以并发多个线程,每个线程可以并行处理不同的任务. ...

  3. 我的Python成长之路---第七天---Python基础(22)---2016年2月27日(晴)

    socket网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

  4. 2016年2月16日开始,每天一篇,记录学习心得,【基本技能篇】&gt&semi;&gt&semi;开篇《如何阅读一本书——心得》

    如何阅读一本书——心得 ——2016年2月12日 要达到阅读的所有目的,就必须在阅读不同书籍的时候,运用适当的不同速度.读的太快或太慢,都一无所获. 四个阅读层次:①基础阅读,具有基本阅读的能力,包括 ...

  5. Python array&comma;list&comma;dataframe索引切片操作 2016年07月19日——智浪文档

    array,list,dataframe索引切片操作 2016年07月19日——智浪文档 list,一维,二维array,datafrme,loc.iloc.ix的简单探讨 Numpy数组的索引和切片 ...

  6. Yoshua Bengio 2016年5月11日在Twitter Boston的演讲PPT

    Yoshua Bengio最新演讲:Attention 让深度学习取得巨大成功(46ppt) Yoshua Bengio,电脑科学家,毕业于麦吉尔大学,在MIT和AT&T贝尔实验室做过博士后研 ...

  7. 2016年12月31日 星期六 --出埃及记 Exodus 21&colon;26

    2016年12月31日 星期六 --出埃及记 Exodus 21:26 "If a man hits a manservant or maidservant in the eye and d ...

  8. 2016年12月30日 星期五 --出埃及记 Exodus 21&colon;25

    2016年12月30日 星期五 --出埃及记 Exodus 21:25 burn for burn, wound for wound, bruise for bruise.以烙还烙,以伤还伤,以打还打 ...

  9. 2016年12月29日 星期四 --出埃及记 Exodus 21&colon;24

    2016年12月29日 星期四 --出埃及记 Exodus 21:24 eye for eye, tooth for tooth, hand for hand, foot for foot,以眼还眼, ...

随机推荐

  1. Oracle sql语句执行顺序

    sql语法的分析是从右到左 一.sql语句的执行步骤: 1)词法分析,词法分析阶段是编译过程的第一个阶段.这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构 ...

  2. java&period;lang&period;Class&lt&semi;T&gt&semi; -- 反射机制

    1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  3. PHP变量在内存中的存储方式

    原文:http://www.phppan.com/tag/refcount/ 每门计算机语言都需要一些容器来保存变量数据.在一些语言当中,变量都有特定的类型,如字符串,数组,对象等等.比如C和Pasc ...

  4. Selenium&plus;WebDriver&plus;Python 定时控制任务

    为了更对得起"自动化测试"的名号,我们可以设置定时任务,使我们自动化脚本在某个时间点自动运行脚本,这样就可以让测试在夜间进行,减少了时间成本.通过程序来控制test case在什么 ...

  5. WebSocket实战之————Workerman服务器的安装启动

    安装php apt-get install php5-cli root@iZ23b64pe35Z:/home/www# php -v PHP 5.5.9-1ubuntu4.20 (cli) (buil ...

  6. 【原创】深度神经网络&lpar;Deep Neural Network&comma; DNN&rpar;

    线性模型通过特征间的现行组合来表达“结果-特征集合”之间的对应关系.由于线性模型的表达能力有限,在实践中,只能通过增加“特征计算”的复杂度来优化模型.比如,在广告CTR预估应用中,除了“标题长度.描述 ...

  7. 无法显示TabHost的setIndicator设置的图片的问题解决办法

    本想做一个 带有图片的 分页显示的demo 但是 自己的代码写的也木有问题 ,所以只有mainifest 有问题了 主要是用到了  Tabhost <TabHost xmlns:android= ...

  8. 循环次数( M - 暴力求解、打表)

    循环次数 Description           我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如,         如果代码中出现         for(i=1;i ...

  9. jmeter测试wordpress使用base64进行鉴权

    1.下载插件 对密码进行加密 2.安装插件 3.使用插件 4.使用base64对上面获取到的密码进行二次加密 echo -n "用户:密码" | base64 将以上命令键入lin ...

  10. css3&lpar;display&rpar;

    实现下拉 <!DOCTYPE html><html><head> <meta charset="utf-8"> <style ...