继承是面向对象的一大特征。要深刻学习继承,需要学会使用调试的技巧来学习它,因为它比较抽象。

  • 继承

    • 继承是指一个具体的类型直接使用另一类型的某些数据成员或函数成员,继承的类是基类(父类),被继承的类是派生类(子类)。所有的类继承Object类,并且拥有Object所有公共方法.
  • 继承类型
    • 实现继承和接口继承

      • 实现继承,表示一个类型派生自一个基类,并且拥有基类所有的公共成员。如果派生类需要重写编写基类的公共方法,则需要使用重写基类方法。
      • 实现继承,利于类型的代码重用和扩展。
      • 接口继承,表示一个类型继承了函数的签名。没有继承任何实现。需要指定类具有某些可用性时可使用接口继承。
    • 多重继承
      • 多重继承,一个类派生自多个类型。
      • C#不支持多重实现继承,但是允许类型派生自多个接口(多重接口继承)
    • 结构和类  
      • 结构不支持实现继承,但支持多接口继承,因为结构本身继承了ValueType类型。
  • 实现继承
    • 实现继承,一个类型派生自一个基类,但是可以派生自多个接口,如果类型既派生基类又派生接口,需要先知道基类,再指定接口。
    • 我们定义的类型,编译器实际上默认指定了类型派生自Object类型。
    • 虚方法
      • 把基类的函数或者属性可以设为virtual,就可以在派生类中进行重写。
      • 在子类中重写虚属性或虚方法,需要使用override关键字显式声明。这样避免了类似C++的潜在错误。
      • 成员字段和静态函数不能声明为virtual,因为virtual只对实例成员有效。
    • 隐藏方法
      • 基类定义的方法与子类定义的方法名相同,且并没有在基类中声明Virtual关键字,所以不是重写方法。而子类隐藏了基类的方法。此时可以使用new关键字来标识子类方法
    • 调用函数基类版本
      • 在子类内部需要调用基类的成员属性,使用base.属性名可以获取和设置基类属性值。同样使用base.方法名可以调用基类的方法。
    • 抽象类和抽象函数
      • 抽象类使用abstract关键字声明。抽象类不能实例化,抽象类中含有抽象方法,抽象方法不需要在抽象类中实现。普通类中不能有抽象方法,有抽象方法的必须是抽象类。抽象类的抽象方法使用abstract声明,抽象类中也允许包含一般方法。
      • 继承抽象类的派生类,需要实现抽象类所有的抽象方法,并且使用override进行重写实现的方法。
    • 密封类和密封方法
      • C#允许把类和方法声明为sealed,对于类,这表示不能继承该类,对于方法,这表示不能重写该方法。
      • 对于自己编写的类或方法进行操作时,可能会对类造成代码混乱或问题,或因为商业原因防止扩展该类,所以进行sealed标记.
    • 派生类的构造函数
      • 类一般有默认的构造函数,如果自定义了构造函数之后,编译器将不再默认构造函数。
      • 子类与基类都会有构造函数,在实例化时,会先执行基类的构造函数,再执行子类的构造函数。
      • 同样子类本身也会有多个构造函数。构造函数又可以调用自身的构造函数。那么执行顺序是什么呢?
      • 先执行基类构造函数,再执行调用的构造函数,最后调用构造函数
      • 在层次结构中添加无参数的构造函数
      • 在子类和基类定义了构造函数,则编译器不再使用默认构造器,并且先调用基类的构造函数再调用子类的构造函数,但是子类也可以调用基类的构造函数,还可以调用本身类中的构造函数。调用基类的构造函数使用base,调用本身类中的构造函数使用this关键字。
      • 在层次结构中添加带参数的构造函数
      • 如果创建了一个带参数的构造函数实例对象,则势必要在创建实例是传入参数进行初始化。
      • 如果类具有一个或多个私有构造函数而没有公共构造函数,则其他类(除嵌套类外)无法创建该类的实例。
  • 修饰符
    • 访问修饰符(可见修饰符)

      • 访问修饰符可以修饰类型、类型成员。修饰符标准介绍如下:
      • 如果类嵌套,也就是说类中含类,那么类中类可以访问类的所有成员,包含私有的信息。
    • 其他修饰符
  • 接口
    • 定义和实现接口
    • 接口不能被实例化,使用interface声明,接口中的所有成员是公有的,因此无需使用访问修饰符修饰。接口中不能定义属性、字段,只能定义方法,方法不能含方法体。继承接口的类,需要实现接口的所有方法。
    • 派生接口
    • 接口是允许继承接口的,接口的实现必须有具体的类型实现。继承接口的类,必须实现继承接口的所有方法以及继承接口的所有方法。
    interface IBook
{
string GetBookName();
}
interface IEnglish : IBook
{
string GetPersonEngName();
}
class MerEngser : IEnglish
{ public string GetPersonEngName()
{
throw new NotImplementedException();
} public string GetBookName()
{
throw new NotImplementedException();
}
}
  • 抽象类和接口的区别:

    • 相同点:
    1. 都可以被继承
    2. 都不能被实例化
    3. 都可以包含方法声明
    4. 派生类必须实现未实现的方法
    • 不同点:
      1. 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
      2. 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”
      3. 接口可以被多重实现,抽象类只能被单一继承
      4. 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中
      5. 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性
      6. 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法
      7. 接口可以用于支持回调,而继承并不具备这个特点
      8. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的
      9. 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
  • 重写和重载的区别:
  • Overload:重载就是在同一个类中,方法名相同,参数列表不同。参数列表不同包括:参数的个数不同,参数类型不同等。
    override:说的是两个类继承,子类重写父类的方法,在调用的时候,子类的方法会覆盖父类的方法,也就是会调用子类的方法。

C#高级编程9-第4章 继承的更多相关文章

  1. C#高级编程9 第16章 错误和异常

    C#高级编程9 第16章 错误和异常 了解这章可以学会如何处理系统异常以及错误信息. System.Exception类是.NET运行库抛出的异常,可以继承它定义自己的异常类. try块代码包含的代码 ...

  2. 读《C#高级编程》第1章问题

    读<C#高级编程>第1章 .Net机构体系笔记 网红的话:爸爸说我将来会是一个牛逼的程序员,因为我有一个梦,虽然脑壳笨但是做事情很能坚持. 本章主要是了解.Net的结构,都是一些概念,并没 ...

  3. C#高级编程9 第18章 部署

    C#高级编程9 第18章 部署 使用 XCopy 进行部署 本主题演示如何通过将应用程序文件从一台计算机复制到另一台计算机来部署应用程序. 1.将项目中生成的程序集复制到目标计算机,生成的程序集位于项 ...

  4. C#高级编程9 第17章 使用VS2013-C#特性

    C#高级编程9 第17章 使用VS2013 编辑定位到 如果默认勾选了这项,请去掉勾选,因为勾选之后解决方案的目录会根据当前文件选中. 可以设置项目并行生成数 版本控制软件设置 所有文本编辑器行号显示 ...

  5. C#高级编程笔记之第二章:核心C#

    变量的初始化和作用域 C#的预定义数据类型 流控制 枚举 名称空间 预处理命令 C#编程的推荐规则和约定 变量的初始化和作用域 初始化 C#有两个方法可以一确保变量在使用前进行了初始化: 变量是字段, ...

  6. C#高级编程9 第14章 内存管理和指针

    C#高级编程9 内存管理和指针 后台内存管理 1) 值数据类型 在处理器的虚拟内存中有一个区域,称为栈,栈存储变量的浅副本数据,通过进入变量的作用域划分区域,通过离开变量的作用域释放. 栈的指针指向栈 ...

  7. python高级编程(第12章:优化学习)1

    # -*- coding: utf-8 -*-# python:2.x__author__ = 'Administrator'#由于5,6,7,8,9,10,11主要是在包,测试之类的学习所以这边就不 ...

  8. C#高级编程9 第11章 Linq

    Linq 1.Linq概述 列表和实体 准备数据: public class Championship { public int Year { get; set; } public string Fi ...

  9. 【读书笔记】C#高级编程 第十九章 程序集

    (一)程序集的含义 程序集是.NET用于部署和配置单元的术语. .NET应用程序包含一个或多个程序集.通常扩展名是EXE或DLL的.NET可执行程序称为程序集. 程序集是自我描述的安装单元,由一个或多 ...

  10. C#高级编程笔记之第一章:.NET体系结构

    1.1 C#与.NET的关系 C#不能孤立地使用,必须与.NET Framework一起使用一起考虑. (1)C#的体系结构和方法论反映了.NET基础方法论. (2)多数情况下,C#的特定语言功能取决 ...

随机推荐

  1. javascript按照指定格式获取上一个月的日期

    //get pre month//get pre month function getPreMonth() { var date=new Date().Format("yyyy-MM-dd& ...

  2. 通过field:global给子元素添加css样式

    {dede:arclist row=5 typeid=200} <li [field:global runphp=’yes’ name=autoindex](@me==1)?@me=”class ...

  3. 如何阻止点击scrollviewer里面的单位内容时,自动滚动

    <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="FocusVisualStyle ...

  4. Codeforces 429B Working out(递推DP)

    题目链接:http://codeforces.com/problemset/problem/429/B 题目大意:两个人(假设为A,B),打算健身,有N行M列个房间,每个房间能消耗Map[i][j]的 ...

  5. mysql数据库查找类型不匹配

    无意中看到10级学长的博客,提到了mysql数据库类型查找不匹配的问题,博客地址是:卢俊达 . 数据库中建表中会对每个属性进行类型划分,然后在查找数据库select时: MySQL 的文档 (Type ...

  6. Shell学习笔记:#*、%*字符串掐头去尾方法

    一.语法 在shell中可以通过#.%对字符串进行掐头去尾操作,使用方法如下: # 表示掐头 % 表示去尾 单个#或%表示最小匹配 双个$或%表示最大匹配  二.例子1 假设我们定义一个变量为: fi ...

  7. Linux命令之远程登录与执行远程主机命令

    实现远程登录的命令 ssh.telnet.rlogin (1)ssh命令 ssh命令是openssh套件中的客户端连接工具,可以给予ssh加密协议实现安全的远程登录服务器.ssh命令用于远程登录上Li ...

  8. D - Round Subset codeforces837d

    D - Round Subset 思路:背包: 代码: #include <cstdio> #include <cstring> #include <iostream&g ...

  9. React + Reflux 渲染性能优化原理

    作者:ManfredHu 链接:http://www.manfredhu.com/2016/11/08/23-reactRenderingPrinciple 声明:版权所有,转载请保留本段信息,否则请 ...

  10. USACO 6.3 Fence Rails(一道纯剪枝应用)

    Fence RailsBurch, Kolstad, and Schrijvers Farmer John is trying to erect a fence around part of his ...