【C#基础详解】(十四)面向对象 继承

2023-11-04

面向过程:

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。

缺点:没有面向对象易维护、易复用、易扩展。

面向对象:

面向对象的三个核心要素是:封装、继承、多态。

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护。

缺点:性能比面向过程低。

面向过程的思维方式,它更加注重这个事情的每一个步骤以及顺序。他比较直接高效,需要做什么可以直接开始干。

面向对象的思维方式,它更加注重事情有哪些参与者,需求里面有哪些对象,这些对象各自需要做些什么事情。将其拆解成一个个模块和对象,这样会更易于维护和拓展。

13.1 继承的含义

1)什么是继承?

继承是在类之间建立一种相交关系,使得新定义的派生类(子类)的实例可以继承已有基类(父类)的特征和能力,而且还可以加入新的特性或者修改已有的特性建立起类的新层次。

注意:object是所有类的基类。

白话:我们可能会在一些类中,写一些重复的成员/方法,我们可以将这些重复的成员/方法,单独地封装到一个类中,作为这些类的父类。

例如:Person是父类(基类)

        Student、Teacher、Driver是子类(派生类)

2)继承的语法:

[public] class 子类类名:父类类名

public class Student:Person{ }

3)继承的作用

① 是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段

② 简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。

③ 提供了软件复用功能,如果说类B继承类A,那么只需要在类B中添加类A中没有的类成员即可,这样能减小代码和数据的冗余度,大大的增加了程序的复用性。

④ 继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。

4)子类继承了什么

子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。

子类没有继承父类的构造函数,但是,子类会默认地调用父类的无参数的构造函数,创建父类对象,让子类可以使用父类中的成员。所以,如果在父类中重写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。

解决办法:

① 在父类中重新写一个无参数的构造函数。

② 在子类中显示的调用父类的构造函数,使用关键字:base()。

13.2 继承的特点

1)继承的特点:

① 派生类是对基类的扩展,派生类可以添加新的成员,但不能移除已经继承的成员的定义。

② 继承可以传递。比如说类C继承类B,类B又继承类A,那么类C不但继承了类B声明的成员,同时也继承了类A声明的成员。

③ 构造函数和析构函数不能直接被继承,除此之外其他成员可以直接被继承。基类中成员的访问方式只能决定派生类中能否访问它们。

④ 派生类如果定义了与基类成员名相同的新成员,那么就可以覆盖基类中的成员。但是这并不是删除了这些成员,而是不能访问再它们而已。

new关键字:1.创建对象 2.隐藏从父类那里继承过来的同名成员,隐藏的后果就是子类调用不到父类的成员

⑤ 基类可以定义虚方法、虚属性及虚索引指示器,它的派生类可以重载这些成员,从而展示出它们的多态性。

⑥ 派生类中能从一个类中继承,可以通过接口来实现多重继承。

2)继承的特性:

单根性:一个子类只能有一个父类。

传递性:可以一个传递一个(爷爷传父亲,父亲传儿子)

 13.3 继承的练习

//1)创建父类:
    public class Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private int _age;
        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }
        private char _gender;
        public char Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }
        public Person(string name,int age,char gender)
        {
            this.Name = name;
            this.Age = age;
            this.Gender = gender;
        }
    }

//2)创建Driver子类:
    public class Driver:Person
    {
        private int _driveTime;
        public int DriveTime
        {
            get { return _driveTime; }
            set { _driveTime = value; }
        }
        public void DriverSayHello()
        {
            Console.WriteLine("我叫{this.Name},我是司机,我年龄是{this.Age},我是{this.Gender}人,我的驾龄是{this.DriveTime}");
        }
        public Driver(string name,int age,char gender,int driveTime) : base(name, age, gender)
        {
            this.DriveTime = driveTime;
        }
    }

//3)创建Programmer子类:
    public class Programmer:Person
    {
        private int _workYear;
        public int WorkYear
        {
            get { return _workYear; }
            set { _workYear = value; }
        }
        public void ProgrammerSayHello()
        {
            Console.WriteLine("我叫{this.Name},是一个程序员,我年龄是{this.Age},我是{this.Gender}生,我的工作年限是{this.WorkYear}年");
        }
        public Programmer(string name,int age,char gender,int workYear) : base(name, age, gender)
        {
            this.WorkYear = workYear;
        }
    }

//4)创建Reporter子类:
    public class Reporter:Person
    {
        private string _hobby;
        public string Hobby
        {
            get { return _hobby; }
            set { _hobby = value; }
        }
        public void ReporterSayHello()
        {
            Console.WriteLine("我是{this.Name},我是记者,我的爱好是{this.Hobby},我是{this.Gender}生,我今年{this.Age}岁了");
        }
        public Reporter(string name,int age,char gender,string hobby) : base(name, age, gender)
        {
            this.Hobby = hobby;
        }
    }

//5)在Main函数调取:
static void Main(string[] args)
{
    Reporter r = new Reporter("zs", 22, '男',"拍照");
    r.ReporterSayHello();
    Programmer p = new Programmer("ls", 23, '男',4);
    p.ProgrammerSayHello();
    Driver d = new Driver("ww", 35, '男',15);
    d.DriverSayHello();
    Console.ReadKey();
}

输出结果:

我是zs,我是记者,我的爱好是拍照,我是男生,我今年22岁了

我叫ls,是一个程序员,我年龄是23,我是男生,我的工作年限是4年

我叫ww,我是司机,我年龄是35,我是男人,我的驾龄是15

13.3 里氏转换

1)含义:

① 子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替。

② 如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

注意:子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。

例如:

Person p = new Student();

Student ss = (Student)p;

2)is关键词和as关键词:

① is:表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false。

if (p is Student)
{
    Student ss = (Student)p;
    ss.StudentSayHello();
}
else
{
    Console.WriteLine("转换失败");
}
Console.ReadKey();

② as:表示类型转换,如果能够转换则返回对应的对象,否则返回一个null。

Student t = p as Student;
t.StudentSayHello();
Console.ReadKey();

3)里氏转换练习:

    class Program
    {
        static void Main(string[] args)
        {
            //创建10个对象,通过个循环去调用他们各自打招呼的方法
            Person[] pers = new Person[10];  //Person的数组
            Random r = new Random();  //随机值
            for (int i = 0; i < pers.Length; i++)
            {
                int rNumber = r.Next(1, 5);
                switch (rNumber)//给数组赋值
                {
                    case 1:
                        pers[i] = new Student();
                        break;
                    case 2:
                        pers[i] = new Teacher();
                        break;
                    case 3:
                        pers[i] = new MeiLv();
                        break;
                    case 4:
                        pers[i] = new Person();
                        break;
                }
            }
            for (int i = 0; i < pers.Length; i++)
            {
                if (pers[i] is Student)
                {
                    ((Student)pers[i]).StudentSay();
                }
                else if (pers[i] is Teacher)
                {
                    ((Teacher)pers[i]).TeacherSay();
                }
                else if (pers[i] is MeiLv)
                {
                    ((MeiLv)pers[i]).MeiLvSay();
                }
                else
                {
                    pers[i].PersonSay();
                }
            }
            Console.ReadKey();
        }
    }
    public class Person
    {
        public void PersonSay()
        {
            Console.WriteLine("我是人类");
        }
    }
    public class Student : Person
    {
        public void StudentSay()
        {
            Console.WriteLine("我是学生");
        }
    }
    public class Teacher : Person
    {
        public void TeacherSay()
        {
            Console.WriteLine("我是老师");
        }
    }
    public class MeiLv : Person
    {
        public void MeiLvSay()
        {
            Console.WriteLine("我是美女");
        }
    }

输出结果:

是随机不同角色打招呼的十条语句

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C#基础详解】(十四)面向对象 继承 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • vscode保存以后或者切换文件以后卡顿,代码提示卡顿

    主要原因 可能是因为你们装了这个扩展 导致vscode会对所有文件进行格式化 一般是开启了vscode保存快捷键格式化以后才会出现这个问题 解决方案 把这个快捷键改一下就好 一般问题是显示什么 正在启动格式化程序 然后每切换一个页面都要改一
  • 网络分析工具Wireshark Network Analyzer

    监听端口10001过滤设置 port 10001
  • go: 配置 vim 高亮插件

    在早期的 golang 源代码包里面是有 vim 插件的 但是呢 到了1 4的源码包的时候 就删除了 vim 插件 所以我们需要从 1 3 3 版本的代码中获得 vim配置 一 官网下载 可以从 golang 官网 Downloads Th
  • date到期(逾期)提醒的逻辑分析,例如快到一年提前一个月提醒

    需求 如快到一年时 提前一个月进行提醒 伪代码 create date x expire date 过期的肯定不用管 expire date m tip date tip date 就是提示开始的时间 所以这个sql大概应该这么写 crea
  • 解决由于已经达到 MaxReports 限制,没有写入 apport 报告的错误

    解决由于已经达到 MaxReports 限制 没有写入 apport 报告的错误 现将info文件夹更名 sudo mv var lib dpkg info var lib dpkg info old 再新建一个新的info文件夹 sudo
  • 初识Qt,几种写界面的方法

    1 我们可以直接在新建项目中选择Application中的Qt Widgets Application 此时Qt会为我们直接生成 ui文件 以及对应得 h头文件 cpp源文件 那么我们需要做的就只是在ui的设计下添加一些我们想让界面拥有的东
  • 重置或修改系统(Linux/windows/宝塔)密码

    一 linux忘记密码 3步重置root密码 虚拟机多了之后 root密码就不好记住了 忘了密还有这种方法修改哦 1 在启动项界面按 e 进入修改页面 2 找到linux16这一行 在末尾添加 rd break 3 再按Ctrl X进入单用
  • 浏览器中输入url请求之后发生的事情?

    一 浏览器查找域名的IP地址 1 请求一旦发起 比如 www baidu com 浏览器第一件事就是 解析这个域名 浏览器先查看本地硬盘的hosts文件 看看其中有没有和这个域名对应的规则 如果有的话 就直接使用hosts文件里面的ip地址
  • Java Excel导出复杂excel表格样式之ExcelUtil工具类

    Java Excel导出包括普通导出及复杂表格样式 主要是对于需要进行行列合并的列进行特殊处理 计算清楚起始行 结束行 起始列 结束列 普通导出可以是所有列 也可以是包含某些列 或者排除某些列 1 效果图 2 原理 如对于上图中的覆盖能力
  • java 文件拷贝的四种方式

    1 java 移动文件的方式有几种 在 Java 中 可以使用多种方法来移动文件 使用 java nio file Files 类的 move 方法 import java nio file Files import java nio fi
  • 1. AJAX: 2. JSON

    内容 1 AJAX 2 JSON AJAX 1 概念 ASynchronous JavaScript And XML 异步的JavaScript 和 XML 1 异步和同步 客户端和服务器端相互通信的基础上 客户端必须等待服务器端的响应 在
  • Android RecyclerView实现树形列表

    前段时间公司有个项目 需要展示客户关系的树形列表 当时网上找了一些资料 有些觉得挺复杂的 有些测试下来有bug 最终决定自己解决 最底下有demo 需要源码的同学可以下载 效果图 带节点的展开与收缩 并且可以实现项的单选 选中项字体为蓝色
  • Mac office 字体和字号显示问题

    Sierra英文的操作系统 word的没有常见的 宋体 等字体选项 而且字号的单位只有磅数 这时可以通过修改word默认的编辑语言解决 打开word的偏好设置 点击 East Asian Language 选择下拉菜单中的中文选项 重启之后
  • UPF learning4: supply power network 相关

    Supply network包含了下面3种元素 supply nets 电线 supply ports 插座 和power switch 开关 create supply port 创建一根电源 create supply net 创建一根
  • android 启动过程中如何清理cache,android 开发过程中涉及到的清除缓存操作

    标签 android 开发过程中会遇到很多缓存 常常使人摸不清楚 这里总结一下 希望下次遇到缓存相关问题能有所帮助 Clean Project 在这里插入图片描述 其中执行 clean 时会找到根项目和所有子项目的 clean task 所
  • 通过Maven命令创建Web项目

    1 创建Web项目 mvn archetype create DgroupId com demo 项目组标识 DartifactId omss 项目名称 DarchetypeArtifactId maven archetype webapp
  • 火爆全网的chat GPT 在煤矿智能问答方面的应用

    测试了19个煤矿智能化 综采方面的问题 甚至会自己写代码 看看chatGPT表现如何 什么是智能化煤矿 什么是记忆割煤 目前记忆割煤都存在哪些问题 煤矿数字孪生技术可以用哪些开源的应用来实现 智能化煤矿未来可以发展到什么程度 提供煤矿智能化
  • git仓库规范

    多人协作 项目名称 demo 我的名字 kk 1 前置概念 主目录 develop 开发目录 dev 主分支 develop demo 开发分支 dev demo kk 2 主目录 develop 该目录下可以有很多项目的分支 dev目录下
  • AI三大主义:符号主义、联结主义、行为主义

    一 符号主义 symbolicism 符号主义 symbolicism 逻辑主义 Logicism 心理学派 Psychlogism 计算机学派 Computerism 其原理主要为物理符号系统 即符号操作系统 假设和有限合理性原理 早期的
  • 【C#基础详解】(十四)面向对象 继承

    面向过程 优点 性能比面向对象高 因为类调用时需要实例化 开销比较大 比较消耗资源 比如单片机 嵌入式开发 Linux Unix等一般采用面向过程开发 性能是最重要的因素 缺点 没有面向对象易维护 易复用 易扩展 面向对象 面向对象的三个核