.NET Core CSharp初级篇 1-6 类的多态与继承

.NET Core CSharp初级篇 1-6

本节内容为类的多态与继承

简介

终于讲到了面向对象三大特性中的两大特性——继承与多态。通过继承与多态,我们能很好的将类的拓展性发挥到了极致。在下面的内容讲解中,我们将从各个方面对继承和多态进行刨析。

继承

继承事实上是一个非常好理解的语法,在C#中实现继承使用A:B,表示A类继承B类。子类(一称为派生类)继承于父类(一称为基类)就好比孩子继承了父亲的一切,但是孩子总归是有自己的个性的,而父亲也有一些不会告诉孩子的事情。如果我们从之前的访问控制符这一部分进行理解的话,你可以这样描述这个“融洽”的父子关系。

假定有以下这个例子:塞巴斯蒂安·艾奎斯(父类)是一个欧洲宫廷的贵族,67岁,他是一个子爵,并且掌握了一个惊天大秘密不能告诉任何人,只能烂在肚子里。他育有一子名叫麦克·艾奎斯,由于塞巴斯蒂安·艾奎斯年老体弱,当家里需要钱的时候,他会让自己的儿子带上银行卡前往atm机取钱。儿子的车和他的车一模一样,每次儿子让管家开车的时候都必须说清楚:“我要开我父亲的车。”,或者:“今天我开我自己的车”。如果他没有说,那么管家会默认的取出儿子的车。他家还有一个大庄园闲置可以用于开发,只要父亲同意,那么儿子可以自由开发。

对于这个例子,你需要得出的结论是:

  • 如果塞巴斯蒂安·艾奎斯(父类)没有出生,那么麦克·艾奎斯(子类)也不存在。(子类实例化时必定先调用父类构造方法)
  • 对于塞巴斯蒂安·艾奎斯(父类),他的名字属于大家都可以知道的(public),谁都可以轻易的得到。但是想拥有这个名字,却只能是他的家族的人才可以(继承后才能获得父类的字段)。
  • 对于前往ATM机取钱这件事,取款密码只可能告诉他的儿子,别人是不能得到的。(protected可以被子类访问,但是其余不可访问)
  • 塞巴斯蒂安·艾奎斯(父类)知道一个秘密,这个秘密只有他本人才知道(private),包括他的儿子也不可能知晓(子类无法获取private)
  • 因为父子俩的车一模一样,取车需要特别说明(子类和父类函数签名一致时,父类函数默认会隐藏,除非显式的说明)
  • 大庄园是父亲的,但是可以被儿子取改造(父类函数指定为virtual时,子类可以重写父类函数)

通过这一些刨析,我认为你应该已经清楚了七八分继承的意思了。这里需要介绍一下我们的base关键字,base关键字在子类中体现为调用父类的方法。

特别的,你需要注意的是,C#对于类与类的继承只支持单继承,如果你试图实现多继承,你可以使用接口作为媒介和桥梁。

我们现在用一段代码演示完我们的继承,我们这个教程更多的是引导你去思考,而不是让你如同一些速成培训班出来的一样,没有独立的思考能力。

class Father
{
    public Father()
    {
        Console.WriteLine("Father Method");
    }
    private string MSGSecret;
    protected string BankSecret;
    public string Name;
    public string Car;
    protected void test()
    {

    }
}
class Son:Father
{
    public Son()
    {
        Console.WriteLine("Son Method");
    }
    //隐式的生成了这三个字段
    //protected string BankSecret;
    //public string Name;
    //public string Car;
    public string Car;
    public void getCar()
    {
        base.Car;//父类
        this.Car;//子类
        base.test()//调用父类方法,如果签名不冲突,可以省略base
    }
}
Son s = new Son();//思考一下这里会输出什么?

多态

多态是一个并不困难的东西,在继承和接口中我们讲到的重写其实就是多态性的一种类型了。之前我们简单的举过一个例子来说明多态:人和鲤鱼都是动物,但是人用肺进行呼吸,而鲤鱼用鳃进行呼吸。这个例子就很好的体现了多态。利用下面这段代码来解释吧。

class Animal
{
    //通过抽象方法实现多态
    abstract void Breathing();
    //虚方法实现多态
    virtual void Eat()
    {
    }
}
class Human:Animal
{
    override void Breathing()
    {

    }
    override void Eat()
    {

    }
}
class Fish:Animal
{
    override void Breathing()
    {

    }
    new void Eat()
    {

    }
}
Animal ah = new Human();
Animal af = new Fish();
Fish f = new Fish();

注意看最后几行,ah和af各属于Human和Fish的对象,但是当方法调用的时候,统一调用父类中的方法,并且加载子类中的重写和实现。

ah.Eat();//调用父类的Eat(),但是以Human类中的重写方法为实现
af.Eat();
f.Eat();

这三者的区别在哪里?事实上你只需要知道,多态性就是通过父类去管理子类,让子类遵循父类的规范。当子类使用从父类继承的方法的时候,是去调用父类的方法,但是使用子类的实现。特别的,如果你在方法中使用new修饰符,那么这个方法将会和父类毫无关系,就如这个单词的意思一样,这是一个新的函数,不是父类中的函数。现在你可以试着分析上述三个函数调用的各是哪个类中的方法。

多态最大的有点就是你可以通过一个基类或者接口去管理所有继承于他们的子类的函数方法,并且同一个函数可以有多种实现方法。

如果你使用接口和抽象类去实现多态,实现的方法也是一样的,只不过是基类型无法实例化。

Github

BiliBili主页

WarrenRyan‘s Blog

博客园

原文地址:https://www.cnblogs.com/WarrenRyan/p/11241566.html

时间: 2024-01-13 20:34:37

.NET Core CSharp初级篇 1-6 类的多态与继承的相关文章

python开发面向对象基础:接口类&抽象类&多态&多继承

一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能 开发中容易出现的问题 1 class Alipay: 2 ''' 3 支付宝支付 4 ''' 5 def pay(self,money): 6 print('支付宝支付了%s元'%money) 7 8 class Applepay: 9 ''' 1

实验五——类的多态,继承和派生2

Part1:验证型实验 1.在派生类函数中,如果是使用对象名.成员名进行访问,则最后运行结果是访问每一个派生类中的成员函数: 2.如果是通过指针来进行访问那么只会访问base1当中的成员函数,因为第一个程序里的BASE1并没有虚函数,所以base2和derived中的成员函数无法将其覆盖,所以只能访问指针当面默认指向的BASE1的成员函数,然而第二个程序使用了虚函数,虚函数的作用是通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数,第二个程序中的base1使用虚函数virtual,即此

植物类(多态和继承)

//#include<iostream> //#include<string> //using namespace std; // //class Botany //{ //public: // Botany(const string& name="") // :_name(name) // { // s_Count++; // } // Botany(const Botany& b) // :_name(b._name) // { // s_C

.NET Core C# 中级篇2-7 文件操作

.NET Core CSharp 中级篇2-7 本节内容为文件操作 简介 文件操作在我们C#里还是比较常见的,例如我们读取Excel.Txt文件的内容,在程序中,这些文件都是以流的方式读取进入我们内存中,本节内容会详细的讲解有关文件的操作的方法. 我们从最大的驱动器开始往文件这个最小的开始讲解 驱动器读取 在Windows操作系统中,存储介质统称为驱动器,硬盘由于可以划分为多个区域,每一个区域称为一个驱动器..NET提供DriveInfo类和 DriveType枚举型,以方便在程序中直接使用驱动

内存泄露之常见问题解决--初级篇

身为一个段子猿,我决定来写写最近的学习心得. 1.简介 在整个Android开发过程中,内存泄露是导致OOM的一个重点因素.大概意思就是:GC无法回收原本应该被回收的对象,这个对象就引发了内存泄露.那有什么危害呢?手机的内存大小是有限的,如果不能释放的话,你就无法创建新的对象,你的新界面等等就无法正常运行,然后程序就OOM了(OutOfMemory). 2.OOM以及内存泄露 OOM通俗点讲就是,你家里有2个厕所,本来你和你老婆用的话,都是够用的,有一天你不小心造人了,从此家里有了1+1=3个人

python_way ,day7 面向对象 (初级篇)

面向对象 初级篇 python支持 函数 与 面向对象 什么时候实用面向对象? 面向对象与函数对比 类和对象 创建类 class 类名 def 方法名(self,xxxx) 类里面的方法,只能对象去调用 对象 = 类名() 通过对象执行方法 对象.方法名(xxxx) 设计,增删改查功能 函数式: def fetch(self,host,port name passwd,sql) pass def create(self,host,port name passwd,sql) pass def re

(转)25个增强iOS应用程序性能的提示和技巧--初级篇

(转)25个增强iOS应用程序性能的提示和技巧--初级篇 本文转自:http://www.cocoachina.com/newbie/tutorial/2013/0408/5952.html 在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致用户的差评.然而由于iOS设备的局限性,有时候要想获得良好的性能,是很困难的.在开发过程中,有许多事项需要记住,并且关于性能影响很容易就忘记. 本文收集了25个关于可以提升程序性能的提示和技巧,把

ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇(转)

ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇 阅读目录 ASP.NET Identity 前世今生 建立 ASP.NET Identity 使用ASP.NET Identity ASP.NET Identity 其他API介绍 小节 在之前的文章中,我为大家介绍了OWIN和Katana,有了对它们的基本了解后,才能更好的去学习ASP.NET Identity,因为它已经对OWIN 有了良好的集成. 在这篇文章中,我主要关注ASP.NET Identity的建

【Java】在Eclipse中使用JUnit4进行单元测试(初级篇)

本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数都完全正确,因为如果我们今后如果对程序进行扩展,用到了某个函数的其他功能,而这个功能有bug的话,那绝对是一件非常郁闷的事情.所以说,每编写完一个函数之后,都应该对这个函数