概念:

在上一节课中学习了如何定义类,用类当做模板来声明我们的数据。

很多类中有相似的数据,比如在一个游戏中,有Boss类,小怪类Enemy,这些类他们有很多相同的属性,也有不同的,这个时候我们可以使用继承来让这两个类继承自同一个类。

分类:

实现继承: 表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。 在实现继承中,派生类型采用基类型的每个函数的实现代码,除非在派生类型的定义中指定重写某个函数的实现代码。 在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承非常有用。

接口继承: 表示一个类型只继承了函数的签名,没有继承任何实现代码。 在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。

多重继承:

C#不支持多重实现继承。 而 C#允许类型派生自多个接 口— — 多重接口继承。 这说明,C#类可以派生自另一个类和任意多个接口。更准确地说, System.Object 是一个公共的基类,所 以每个 C#(除了Object类之外)都有一个基类,还可以有任意多个基接 口。

实现继承:

  1. 如果要声明派生自另一个类的一个类,就可以使用下面的语法:
  2. class MyDerivedClass : MyBaseclass
  3. {
  4. // functions and data members here
  5. }
  6. 如果类(或 结构)也 派生 自接 口,则用逗号分隔列表中的基类和接 口:
  7. public class MyDerivedClass: MyBaseClass , IInterface1 , IInterface2
  8. {
  9. // etc.
  10. }

接口继承:

  1. namespace _012_定义和实现接口 {
  2. interface IA //不能有字段,方法不能被实现
  3. {
  4. void Method1();
  5. }
  6. }
  7.  
  8. namespace _012_定义和实现接口 {
  9. interface IB:IA
  10. {
  11. void Method2();
  12. }
  13. }
  14.  
  15. namespace _012_定义和实现接口 {
  16. interface IFly
  17. {
  18. void Fly();
  19. void MethodA();
  20. }
  21. }
  22. //继承了接口就要实现继承的接口中的所有方法,包括接口的父接口中的方法
  23. namespace _012_定义和实现接口 {
  24. class Bird :IFly,IB{
  25. public void Fly()
  26. {
  27.  
  28. }
  29.  
  30. public void MethodA()
  31. {
  32.  
  33. }
  34.  
  35. public void Method1()
  36. {
  37.  
  38. }
  39.  
  40. public void Method2()
  41. {
  42.  
  43. }
  44. }
  45. }

虚方法:

  1. 把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:
  2. class MyBaseClass{
  3. public virtual string VirtualMethod(){
  4. return "Method is called in base class";
  5. }
  6. }
  7. 在派生类中重写另外一个函数时,要使用override关键字显示声明
  8. class MyDerivedClass:MyBaseClass{
  9. public override string VirtualMethod(){
  10. return "Method is called in derivedclass.";
  11. }
  12. }
  13. 我们在子类里面重写虚函数之后,子类对象不管在哪里调用都是调用重写之后的方法,可以不重写,不重写就调用父类的方法,将子类对象赋给父类对象也会调用子类中重写的方法

隐藏方法(密封方法):

  1. 如果签名相同的方法在基类和派生类中都进行了声明,但是该方法没有分别声明为virtualoverride,派生类就会隐藏基类方法。(要使用new关键字进行声明)
  2. 基类
  3. class MyBaseClass{
  4. public int MyMethod(){
  5. }
  6. }
  7. 派生类(在派生类中把基类同名的方法隐藏掉了)
  8. class MyDerivedClass :MyBaseClass{
  9. public new void MyMethod() //有没有new都可以,只是表示是隐藏方法,但是父类的方法还是存在的,重写的话父类的方法在子类中是不存在了
    {
  10. }
  11. }

Enemy enemy;
enemy = new Boss();//父类声明的对象,可以使用子类去构造 子类声明的对象不可以使用父类构造
//enemy虽然使用父类进行了声明,但是使用了子类构造,所以本质上是一个子类类型的,我们可以强制类型转换转换成子类类型
Boss boss = (Boss)enemy;
boss.Attack();

  1.  

Enemy enemy = new Enemy();
Boss boss =(Boss) enemy;//一个对象是什么类型的 主要看它是通过什么构造的 这里enemy使用了父类的构造函数,所以只有父类中的字段和方法, 不能被强制转换成子类

  1.  

Enemy boss = new Boss();
boss.Move();//隐藏方法: 如果使用子类声明的对象,调用隐藏方法会调用子类的,如果使用父类声明对象,那么就会调用父类中的隐藏方法

this和base关键字:

this可以访问当前类中定义的字段,属性和方法,有没有this都可以访问,有this可以让IDE-VS编译器给出提示,另外当方法的参数跟字段重名的时候,使用this可以表明访问的是类中的字段。

base可以调用父类中的公有方法和字段,有没有base都可以访问,但是加上base.IED工具会给出提示,把所有可以调用的字段和方法罗列出来方便选择

  1. 使用base关键字调用父类构造函数的语法如下:
  2. 子类构造函数:base(参数列表)
  3. 使用base关键字调用父类方法的语法如下:
  4. base.父类方法();
  5. using System ;
  6. class Teacher//老师类
  7. {
  8. public Teacher()//构造函数1
  9. {
  10. Console.WriteLine ("我是一位教师。");
  11. }
  12. public Teacher(string str)//构造函数2
  13. {
  14. Console.WriteLine ("老师,"+str);
  15. }
  16.  
  17. public void OutPut()//自定义方法
  18. {
  19. Console.WriteLine ("输出方法");
  20. }
  21.  
  22. private string name;
  23. public string Name//属性
  24. {
  25. get{return this.name;}
  26. set{this.name=value;}
  27. }
  28. public void getName()
  29. {
  30. Console.WriteLine ("我的名字是"+name);
  31. }
  32. }
  33.  
  34. class Jack:Teacher
  35. {
  36. static string hello="你好";
  37. public Jack():base(hello)//子类的构造函数继承的为父类第二个构造函数,注意写法
  38. {
  39. }
  40. public void myOutPut()//自定义函数
  41. {
  42. base.OutPut ();//引用父类的函数
  43. }
  44. public string myName//自定义属性
  45. {
  46. get{return base.Name ;}
  47. set{base.Name ="王"+value;}
  48. }
  49. }
  50. class Test
  51. {
  52. static void Main()
  53. {
  54. Jack j=new Jack ();//输出“老师,你好”
  55. j.myOutPut ();//输出"输出方法"
  56. j.myName ="猫骨";
  57. j.getName ();//输出“王猫骨”
  58. }
  59. }
  60. 注意:base()调用父类构造函数时,不需要再次指定参数的类型,因为在子类中已经定义了这些参数,在base()中只需指定变量名即可,参数的类型必须和父类中的一致。

抽象类:

  1. C#允许把类和函数声明为 abstract。 抽象类不能实例化,抽象类可以包含普通函数和抽象函数,抽象函数就是只有函数定义没有函数体。 显然,抽象函数本身也是虚拟的Virtual(只有函数定义,没有函数体实现)。
  2. 类是一个模板,那么抽象类就是一个不完整的模板,我们不能使用不完整的模板去构造对象。,但是可以声明对象
  1. abstract class Bird//一个抽象类 就是一个不完整的模板
  2. {
  3. private float speed;
  4.  
  5. public void Eat()
  6. {
  7.  
  8. }
  9.  
  10. public abstract void Fly();//抽象方法,没有实体
  11. }
  12.  
  13. class Crow:Bird {//我们继承了一个抽象类的时候,必须去实现抽象方法
  14. public override void Fly()
  15. {
  16. Console.WriteLine("乌鸦在飞行");
  17. }
  18. }

密封类和密封方法:

  1. C#允许把类和方法声明为 sealed。 对于类 ,这表示不能继承该类;对于方法表示不能重写该方法。
  2. sealed FinalClass
  3. {
  4. // etc
  5. }
  6. 什么时候使用 密封类和密封方法?
  7. 防止重写某些类导致代码混乱,在重写的方法override前加sealed
  8. 商业原因

派生类的构造函数:

  1. ,在子类中调用父类的默认构造函数(无参)(会先调用父类的,然后是子类的)
  2. public class MyDerivedClass{
  3. public MyDerivedClass():base(){
  4. //do something
  5. }
  6. }
  7. 在这里 base()可以直接不写,因为默认会调用父类中的默认构造函数
  8. ,调用有参数的构造函数
  9. public class MyDerivedClass{
  10. public MyDerivedClass(string name):base(name){
  11. //do something
  12. }
  13. }

修饰符:

修饰符,用来类型或者成员的关键字。修饰符可以指定方法的可见性。

public 和private修饰字段和方法的时候,表示该字段或者方法能不能通过对象去访问:

只有public的才可以通过对象访问

private(私有的)只能在类模板内部访问。

protected 保护的,当没有继承的时候,它的作用和private是一样的,当有继承的时候,protected表示可以被子类访问的字段或者方法

类型的修饰符:

public class ...

class ...

前者可以在别的项目下访问,后者不行

其他修饰符:

static可以修饰字段或者方法,修饰字段的时候,表示这个字段是静态的数据,叫做静态字段或者静态属性,修饰方法的时候,叫做静态方法,或者静态函数 使用static修饰的成员,只能通过类名访问 当我们构造对象的时候,对象中只包含了普通的字段,不包含静态字段

实现继承+接口继承+虚方法+隐藏方法+this/base+抽象类+密封类/方法+修饰符的更多相关文章

  1. python的类的继承-接口继承-归一化设计

    1.先在子类本身找,如果子类没有,会去父类找 class Dad: '这个是爸爸类' money=10#Dad类的数据属性 def __init__(self,name): print("爸 ...

  2. this/super/static/final/匿名对象/继承/抽象类/访问权限修饰符

    1.this关键字的作用     1)调用本类中的属性;     2)调用本类中的构造方法;且只能放首行,且必须留一个构造方法作为出口,即不能递归调用     3)表示当前对象; 2.匿名对象     ...

  3. java 面对对象(抽象 继承 接口 多态)

    什么是继承? 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可. 多个类可以称为子类,单独这个类称为父类.超类或者基类. 子类可以直接 ...

  4. JAVA中方法和变量在继承中的覆盖和隐藏

    出处:http://renyanwei.iteye.com/blog/258304 我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际 ...

  5. JAVA中方法和变量在继承中的覆盖和隐藏(一)

    我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊 ...

  6. python之接口继承

    接口继承 接口继承就是(基类)父类定义好2个函数属性(接口),所有的子类必须有这2个函数属性,缺一不可,不是说省代码的,是用来做强制性约束的 基类里面的方法不用具体的实现,只是一个规范而已 1.1实现 ...

  7. .NET C#基础(2):方法修饰符 - 给方法叠buff

    0. 文章目的   本文面向有一定.NET C#基础知识的学习者,介绍C#中的方法修饰符的含义和使用以及注意事项.   1. 阅读基础   理解C#基本语法(如方法声明)   理解OOP基本概念(如多 ...

  8. 【译文】 C#面向对象的基本概念 (Basic C# OOP Concept) 第一部分(类,对象,变量,方法,访问修饰符)

    译文出处:http://www.codeproject.com/Articles/838365/Basic-Csharp-OOP-Concept 相关文档:http://files.cnblogs.c ...

  9. Java中各种(类、方法、属性)访问修饰符与修饰符的说明

    类: 访问修饰符 修饰符 class 类名称 extends 父类名称 implement 接口名称 (访问修饰符与修饰符的位置可以互换) 访问修饰符 名称 说明 备注 public 可以被本项目的所 ...

随机推荐

  1. git commit -a -m "DM 1、获取aliOssSTS值,计算签名,实现视频PUT/POST2种上传方式上传;"

    git commit -a -m "DM 1.获取aliOssSTS值,计算签名,实现视频PUT/POST2种上传方式上传:" 微信小程序的视频上传

  2. python作用域和JavaScript作用域

    JavaScript 一.JavaScript中无块级作用域 一个大括号一个作用域,就属于块级作用域,在Java和c#才存在块级作用域 function Main(){ if(1==1){ var n ...

  3. SQL Server误删表查看

    SQL Server误删表查看 转自:http://blog.51cto.com/aimax/2134572   SQL Server 完全恢复模式 下恢复误删除的表,进行 精准 恢复 1.  找出被 ...

  4. hadoop学习第三天-MapReduce介绍&&WordCount示例&&倒排索引示例

    一.MapReduce介绍 (最好以下面的两个示例来理解原理) 1. MapReduce的基本思想 Map-reduce的思想就是“分而治之” Map Mapper负责“分”,即把复杂的任务分解为若干 ...

  5. 剑指offer 面试3题

    面试3题: 题:数组中重复的数字 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复 ...

  6. Log level with log4j and Spark

    Log Level Usages OFF This is the most specific, which allows no logging at all FATAL This is the mos ...

  7. Funq之Lambda表达式2

    Last month I started a series of posts covering some of the new VB and C# language features that are ...

  8. Java字段初始化规律:

    Java字段初始化规律: Java进行初始化的地方有两个,初始化块和构造函数,其中初始化块又分为静态初始化块和实例初始化块(以上程序为实例初始化块).静态初始化块是类中由static修饰的初始化块,实 ...

  9. OpenGL学习进程(6)第四课:点、边和图形(一)点

    本节是OpenGL学习的第四个课时,下面介绍OpenGL点的相关知识:     (1)点的概念:     数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点 ...

  10. 07_Warning $HADOOP_HOME is deprecated.去除办法

    Warning $HADOOP_HOME is deprecated.去除办法 警告的出现: 解决方案: 第一种: 去除[/etc/profile]文件中[export HADOOP_HOME=/op ...