面向对象-学习记录1

目标

寒假看了相关视频教程学了面向对象编程,时隔已久,现在回来复习并整理先前笔记

是什么

面向对象是一种思想。从“对象”的角度出发思考问题。

面向对象有三个基本特征:
1.封装
2.继承
3.多态 把面向对象的思想发挥到了最高点


封装

用术语说:封装,即指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

举个例子,假如我们做了个PVZ里的向日葵。那么,以后要产出阳光时,我们只需要知道:种向日葵,种就完事了。而无需关心向日葵内部是如何计算阳光的产出时间等细节,那是面向过程要考虑的事,是已经被封装好了的,我们直接用就好了。

好处
简化了问题。


继承

用术语说:继承,即子类继承父类的特征和行为,使得子类对象具有父类的属性和方法。

举个例子,PVZ里的西瓜投手和冰瓜投手。西瓜投手作为父类,冰瓜投手作为它的子类。前者有的,后者都有,这就是继承。

好处
减少代码冗余。

两个特点

  1. 单根性:一个子类只对应一个父类。
  2. 传递性:子类可调用父类及其父类中的成员。

里氏转换(视频教程里说里氏转换用得很多,一定要记得)

  1. 当方法中需要一个父类作为参数,可拿其子类代替之。(父类变量里装子类对象)
  2. 当父类里装的是子类对象时,可以将父类强制转换为该子类。

转换时可使用的关键字

  1. is 返回布尔值

    //代码片段 Watermelon w = new IceWatermelon(); if(w is IceWatermelon) //变量名 is 类的类型 { IceWatermelon iw = (IceWatermelon) w;//里氏转换 }
  2. as 若转换成功,返回转换后的对象;若失败,则返回null。

    //代码片段 Watermelon w = new IceWatermelon(); IceWatermelon iw = w as IceWatermelon;//里氏转换

多态

用术语说:多态,即让一个对象表现出来多种类型。亦可理解为一个父类拥有多个不同的子类。

举个例子,PVZ里的豌豆们。如果把豌豆射手作为父类,那么可以把寒冰射手、双发射手、机枪射手作为其子类。这三个子类虽然都继承于同一个父类,但互不相同,各有特点,这就是多态。

好处
把各个子类中的公共部分抽取出来,最大限度的取消各子类之间的差异性,减少代码冗余。

三种实现手段

  1. 虚方法
  2. 抽象类
  3. 接口

虚方法

步骤1. 将父类的方法标记为虚方法:在父类方法的返回值前加上关键字virtual,那么该函数可以被子类重写。
步骤2. 在子类的同名方法的返回值前加上关键字override,重写该方法。

class Peashooter { public virtual void Attack() { Console.WriteLine("发射一颗豌豆"); } } class IcePeashooter : PeaShooter { public override void Attack() { Console.WriteLine("发射一颗冰豌豆"); } } class Repeater : PeaShooter { public override void Attack() { Console.WriteLine("发射两颗豌豆"); } } class GatlingPea : PeaShooter { public override void Attack() { Console.WriteLine("发射四颗豌豆"); } }

在虚方法的前提下,父类变量中装着谁的对象,就调用该对象所对应的同名函数。


抽象类

当父类中的方法不知道如何去实现时,可以考虑将父类写成抽象类,将方法写成抽象方法。

步骤1. 使用关键字abstract标记一个类为抽象类,标记一个方法为抽象方法。
步骤2. 在子类的同名方法的返回值前加上关键字override,重写该抽象方法(必须重写父类的所有抽象方法,除非该子类也是抽象类)。

abstract class Plant //定义抽象类Plant { public abstract void Attack();//注意抽象父类的抽象方法无方法体 } class Peashooter : Plant { public override void Attack() { Console.WriteLine("发射一颗豌豆"); } } class IcePeashooter : Plant { public override void Attack() { Console.WriteLine("发射一颗冰豌豆"); } } class Repeater : Plant { public override void Attack() { Console.WriteLine("发射两颗豌豆"); } } class GatlingPea : Plant { public override void Attack() { Console.WriteLine("发射四颗豌豆"); } }

抽象方法不允许有方法体(花括号),有方法体没语句那叫空实现。
抽象类和接口都不允许实例化。


接口

想要多继承时,由于继承的单根性,只能使该子类继承一个接口。

步骤1. 定义一个接口。
步骤2. 在子类中实现接口里的所有成员。

接口中包含一组方法。使用接口可以强制规定其实现类必须要实现这些方法,而每个实现类的实现方式却又可以不同,这很多态。

一个接口可以有多个实现,一个实现类可以实现多个接口。

语法

public interface 接口名(一般为I...able { 成员; }

示例代码片段
还记得PVZ中的特殊关“植物僵尸”吗?

public interface IPlantable //定义一个Plant接口,使僵尸也能拥有植物的能力 { void Attack(); } class PeaZombie : IPlantable { public void Attack() { Console.WriteLine("这个僵尸能发射豌豆"); } } class SquashZombie : IPlantable { public void Attack() { Console.WriteLine("这个僵尸能压扁遇到的第一株植物"); } }

1.接口中的成员不允许添加访问修饰符,默认就是public。
2.接口中的成员不允许有方法体。
3.接口中不能包含字段(接口不存数据)。
4.继承接口的子类必须实现该接口的所有成员。
5.若一个类既继承了接口,又继承了类,那么在语法上,类必须写在接口之前。

参考资料

C#开发课程,一整套课程中的面向对象部分


__EOF__

本文作者OtusScops
本文链接https://www.cnblogs.com/OtusScops/p/14705386.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   AshScops  阅读(97)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示