1. 简单继承
  2. 多态
  3. 接口
  4. 参考

简单继承

最简单的三个类

[csharp] view plaincopy print?
  1. public class Animal {
  2. public Animal()
  3. {
  4. Debug.Log("Construct Animal!");
  5. }
  6. }

public class Animal {public Animal(){Debug.Log("Construct Animal!");}
}
[csharp] view plaincopy print?
  1. public class Mammal : Animal {
  2. public Mammal()
  3. {
  4. Debug.Log("Construct Mamal!");
  5. }
  6. }

public class Mammal : Animal {public Mammal(){Debug.Log("Construct Mamal!");}
}
[csharp] view plaincopy print?
  1. public class Sheep : Mammal
  2. {
  3. public Sheep()
  4. {
  5. Debug.Log("Construct Sheep!");
  6. }
  7. }

public class Sheep : Mammal
{public Sheep(){Debug.Log("Construct Sheep!");}
}

在main里面

[csharp] view plaincopy print?
  1. Sheep sheep = new Sheep();

Sheep sheep = new Sheep();

子类的构造函数会依次执行基类的构造函数,没有异议。

需要注意的是,没有特别声明,子类都会自动去找父类中没有参数的构造函数,如果基类中没有,则需要在子类的构造函数中调用,比如:

[csharp] view plaincopy print?
  1. public class Animal{
  2. int age;
  3. public Animal(int _age)
  4. {
  5. age = _age;
  6. Debug.Log("Construct Animal!");
  7. }
  8. }

public class Animal{int age;public Animal(int _age){age = _age;Debug.Log("Construct Animal!");}
}

则子类的构造函数就要这样写

[csharp] view plaincopy print?
  1. public Mammal():base(0)
  2. {
  3. Debug.Log("Construct Mamal!");
  4. }

    public Mammal():base(0){Debug.Log("Construct Mamal!");}

在基类Animal中添加函数

[csharp] view plaincopy print?
  1. public void Eat()
  2. {
  3. Debug.Log("Animal Eat!");
  4. }

    public void Eat(){Debug.Log("Animal Eat!");}

下面谈一下方法的覆盖

在子类Sheep中覆盖定义Eat方法

[csharp] view plaincopy print?
  1. public new void Eat()
  2. {
  3. Debug.Log("Sheep Eat!");
  4. }

    public new void Eat(){Debug.Log("Sheep Eat!");}

这里的new关键字表示隐藏基类中的方法,官方解释如下:

new 关键字可以显式隐藏从基类继承的成员。隐藏继承的成员时,该成员的派生版本将替换基类版本。虽然可以不使用 new 修饰符来隐藏成员,但将收到编译器警告。如果使用 new 来显式隐藏成员,将禁止此警告。

测试代码:

[csharp] view plaincopy print?
  1. Sheep sheep = new Sheep();
  2. Animal animal = new Sheep();
  3. sheep.Eat();
  4. animal.Eat();

        Sheep sheep = new Sheep();Animal animal = new Sheep();sheep.Eat();animal.Eat();

结果是这样的

没有发生多态行为,声明的基类对象,执行的就是基类方法,声明的子类对象,执行的就是子类方法。

在子类的函数中,都有一个base变量,可以认为是一个对基类的引用,通过base就可以调用基类的方法。

多态

多态就是多态就是父类引用指向子类对象,调用方法时会调用子类的实现,而不是父类的实现,这叫多态。

基类Animal中定义函数

[csharp] view plaincopy print?
  1. public virtual void Birth()
  2. {
  3. Debug.Log("Animal Birth!");
  4. }

    public virtual void Birth(){Debug.Log("Animal Birth!");}

Sheep中overrride一下

[csharp] view plaincopy print?
  1. public override void Birth()
  2. {
  3. Debug.Log("Sheep Birth!");
  4. }

    public override void Birth(){Debug.Log("Sheep Birth!");}

测试代码

[csharp] view plaincopy print?
  1. Sheep sheep = new Sheep();
  2. Animal animal = new Sheep();
  3. animal.Birth();

        Sheep sheep = new Sheep();Animal animal = new Sheep();animal.Birth();

执行结果

有下面两个需要注意的点

1.子类调用父类的方法

当然是直接用base了。

2.继承链中的虚方法

无论在虚拟成员和最初声明虚拟成员的类之间已声明了多少个类,虚拟成员永远都是虚拟的。如果类 A 声明了一个虚拟成员,类 B 从 A 派生,类 C 从类 B 派生,则类 C 继承该虚拟成员,并且可以选择重写它,而不管类 B 是否为该成员声明了重写。

Sealed关键字的用法

Sealed关键字用来阻止派生类重写虚拟成员。还是举例说明。

基类Animal中定义方法

[csharp] view plaincopy print?
  1. public virtual void Move()
  2. {
  3. Debug.Log("Animal Move!");
  4. }

public virtual void Move()
{Debug.Log("Animal Move!");
}

Mammal中sealed override这个函数

[csharp] view plaincopy print?
  1. public sealed override void Move()
  2. {
  3. Debug.Log("Mammal Move!");
  4. }

    public sealed override void Move(){Debug.Log("Mammal Move!");}

这时候在Sheep中已经无法overide这个函数了,因为在Sheep看来,基类的Move是被当作一个普通函数来处理的,如果要定义自己的Move函数,就要加new,像这样

[csharp] view plaincopy print?
  1. public new void Move()
  2. {
  3. Debug.Log("Sheep Move!");
  4. }

    public new void Move(){Debug.Log("Sheep Move!");}

写点代码来测试多态性

[csharp] view plaincopy print?
  1. Animal animal = new Animal(1);
  2. Animal animal1 = new Mammal(1);
  3. Animal animal2 = new Sheep();
  4. Sheep sheep = new Sheep();
  5. animal.Move();
  6. animal1.Move();
  7. animal2.Move();
  8. sheep.Move();

        Animal animal = new Animal(1);Animal animal1 = new Mammal(1);Animal animal2 = new Sheep();Sheep sheep = new Sheep();animal.Move();animal1.Move();animal2.Move();sheep.Move();

运行结果

第一个无话可说,直接执行了Animal的move函数

第二个,正常的多态

第三个有点意思,多态到Mammal就打住了

第四个就是普通的执行Sheep类的成员函数。

abstract关键字的使用

官方解释:abstract 修饰符指示所修饰的内容缺少实现或未完全实现。abstract 修饰符可用于类、方法、属性、索引器和事件。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。

接地气的解释:abstract类用于搭建子类的框架,子类必须实现其中的abstract方法,使用的也是override关键字。

abstract方法和vitual方法的区别

abstract方法没有函数体,子类一定要有对应方法的实现。

vitual方法子类可以选择实现也可以选择不实现。

两个都可以用于实现多态。

抽象类不能实例化。抽象类的用途是提供一个可供多个派生类共享的通用基类定义。例如,类库可以定义一个抽象类,将其用作多个类库函数的参数,并要求使用该库的程序员通过创建派生类来提供自己的类实现。

接口

接口包含类或结构可以实现的一组相关功能的定义。
例如,使用接口可以在类中包括来自多个源的行为。 由于C#语言不支持多重继承,所以该功能很重要。 此外,如果要模拟结构的继承,也必须使用接口,因为它们无法实际从另一个结构或类继承。

定义一个简单的接口,只有接口函数的定义,没有实现。

[csharp] view plaincopy print?
  1. public interface ISay {
  2. void SayHello();
  3. void SayFuck();
  4. }

public interface ISay {void SayHello();void SayFuck();
}

Sheep继承ISay接口

[csharp] view plaincopy print?
  1. public class Sheep : Mammal, ISay

public class Sheep : Mammal, ISay

则Sheep类中必须要有ISay中定义的接口的定义

[csharp] view plaincopy print?
  1. public void SayHello()
  2. {
  3. Debug.Log("ISay Hello");
  4. }
  5. public void SayFuck()
  6. {
  7. Debug.Log("ISay SayFuck");
  8. }

    public void SayHello(){Debug.Log("ISay Hello");}public void SayFuck(){Debug.Log("ISay SayFuck");}

测试代码

[csharp] view plaincopy print?
  1. Sheep sheep = new Sheep();
  2. sheep.SayHello();
  3. sheep.SayFuck();

        Sheep sheep = new Sheep();sheep.SayHello();sheep.SayFuck();

执行结果

接口有下面几个属性

接口类似于抽象基类。实现接口的任何类或结构都必须实现其所有成员。
接口无法直接进行实例化。其成员由实现接口的任何类或结构来实现。
接口可以包含事件、索引器、方法和属性。
接口不包含方法的实现。
一个类或结构可以实现多个接口。一个类可以继承一个基类,还可实现一个或多个接口。

C#中的继承与多态还有接口相关推荐

  1. 【Java】继承、多态、接口

    Java中的继承.多态和接口 1.用类比引入继承概念 众所周知,Java是一门面向对象的语言.如果我们要设计多种多样的交通工具,比如汽车.火车.飞机,虽然这些工具功能不同.形态不同,但是他们很多的基本 ...

  2. C++ 中的继承和多态

    C++ 中的继承和多态 一.继承 二.函数重载.隐藏.覆盖.重写 1.函数重载(Function Overload) 2.函数隐藏(Function Hiding) 3.函数重写与函数覆盖(Funct ...

  3. Java中的继承 与 多态(中)

    先导: 我们在<Java中的继承 与 多态(上)>当中讲解了如下几个问题,  1.继承是什么   2.super关键字   3.特殊考点-父子类中不同代码块的实现顺序 所以现在我们对于继承 ...

  4. 07 面向对象编程-结构、封装、继承、多态、接口

    文章目录 Struct定义 struct 方法 工厂模式 面向对象三大特性 封装 继承 接口 多态 Golang支持面向对象编程,但是和传统面向对象有区别,并不是纯粹面向对象的语言,只能说Golang ...

  5. 面试轻松讲清楚 Java 面向对象的问题与知识(类与对象,封装,继承,多态,接口,内部类...)

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  6. Java SE(六)之面向对象(封装,继承,多态,接口)

    文章目录 类和对象 1. 创建一个类 2. 创建一个对象 3. 访问变量和方法 4. some tips 封装 修饰符 1. 访问控制修饰符 2. 非访问修饰符 (1)static (2)final ...

  7. 如何讲清楚 Java 面向对象的问题与知识?(类与对象,封装,继承,多态,接口,内部类...)

    二 Java面向对象 类和对象 1.1 什么是面向过程?什么又是面向对象? 面向过程--步骤化 面向过程就是分析出实现需求所需要的步骤,通过函数(方法)一步一步实现这些步骤,接着依次调用即可 面向对象 ...

  8. Python中的继承和多态

    本文以生活中的基础现象为切入点,主要介绍了Python基础中继承和多态,包括单继承.多继承的语法.多态常见的 "鸭子类型". 以及如何重写父类的方法都做了详细的讲解. 一.继承的介 ...

  9. java 父类是抽象类 定义private的属性 子类继承_java继承、多态、接口、抽象类定义及应用...

    继承:关键字extends java 中继承是单继承 允许多个子类继承一个父类,不允许一个子类继承多个父类. 继承是继承父类的所有属性和方法,但并不是所有的属性和方法都可被子类调用: 子类继承父类是必 ...

最新文章

  1. [C]计算某一天是该年中的第几天
  2. c语言中24个字母,菜鸟求助,写一个随机输出26个英文字母的程序
  3. Pycharm自定义包的导入
  4. Symfony 4.3 发布,带来搜索引擎自动保护
  5. 分享18道Java基础面试笔试题
  6. 使用pt-heartbeat检测主从复制延迟
  7. mysql参数配置调优详解配置(1)
  8. 新款iPhone SE预约量超40万,拼多多已经安排上,击穿底价2999元?
  9. Docker (一、dockerfile-node.js)
  10. [codeup 5038] 找零钱
  11. XXX客户2020年护网行动总结报告
  12. NAND Flash硬件原理
  13. Matlab画混淆矩阵(多分类)
  14. 大型应用+go+java_企业应用程序,Go比Java更明智!
  15. 计算机网络笔记02---网络边缘和网络核心
  16. 国密加密算法与国际加密算法
  17. Cocoapods的安装 简单教程(有待完善)
  18. clickhouse--物化视图
  19. 在网页中挂马和清除木马的方法
  20. Internet与Web技术的基本概念

热门文章

  1. java set 对象去重_JAVA对象去重
  2. 如意报表插件如何安装_Google Chrome浏览器如何安装插件应用
  3. 用32定时器让电机缓慢转动_实验三 步进电机原理及应用
  4. 什么叫返回路径平面上的间隙_苏州平面设计培训:平面设计师工作流程
  5. python内核_python内核_python内核语言_python版本内核 - 云+社区 - 腾讯云
  6. 中文只占一个字符_一文搞懂字符和字节的含义
  7. 英雄会被表彰,这些技术与代码也将被历史铭记
  8. 为什么需要这么多编程语言?
  9. 电子设计竞赛电源题(1)-电源题简介
  10. mysql 5.6 分区_Mysql5.6—分区表及独享表空间