浅谈C# 抽象类与开闭原则
作者:安静点-- 发布时间:2023-11-07 11:00:08
1.抽象类与抽象方法:
(1)使用关键字abstract修饰的类,称为抽象类.
(2)抽象类只是用到一个类所具有的行为,不能单独通过创建对象来使用.使用new是错误的.可以通过派生类来实现其函数成员的具体逻辑。
(3)抽象类中可以有抽象方法,也可以没有任何抽象方法.只要类中存在一个抽象方法,这个类就是抽象类。
(4)抽象类不能是静态的(static)或者密封的(sealed)
下面就是一个简单的抽象类
abstract class Vehicle
{
public abstract void test();
public void VehicleTest()
{
}
}
class Car : Vehicle
{
public override void test()
{
}
}
2.开闭原则
如果不是为了修改bug,或者是添加新的功能,不要随便更改类的代码。
换句话说,我们应该封装那些确定的,不变的,稳定的,固定的。把不确定的,有可能会改变的成员声明为抽象类,留给子类去实现。
3.我们简单实现了一个继承
class Program
{
static void Main(string[] args)
{
Vehicle raceCar = new RaceCar();
Console.ReadKey();
}
}
/// <summary>
/// 交通工具类
/// </summary>
class Vehicle
{
/// <summary>
/// 停车
/// </summary>
public void Stop()
{
Console.WriteLine("Stopped");
}
/// <summary>
/// 加油
/// </summary>
public void Fill()
{
Console.WriteLine("Fill");
}
}
class Car : Vehicle
{
public void Run()
{
Console.WriteLine("Car is running");
}
}
class RaceCar : Car
{
public void Run()
{
Console.WriteLine("RaceCar is running");
}
}
从上面的代码我们可以看出这是一个继承链,其中Run方法是根据不同种类的车来区别的,所以我们如果想实现多态,比如 Vehicle raceCar = new RaceCar();此时raceCar 对象是调不到Run方法的,因为Vehicle类中没有这个方法,以前对于这种情况的解决方法是在Vehicle中加上Run方法,并且判断有什么类型:
public void Run(string type)
{
if (type == "Car")
{
Console.WriteLine("Car is running");
}
else if (type == "RaceCar")
{
Console.WriteLine("RaceCar is running");
}
else
{
}
}
如上代码,这样的话,当增加新类型的时候还要再改这个基类中的方法,违反了开闭原则( 如果不是为了修改bug,或者是添加新的功能,不要随便更改类的代码),所以需要做一下修改:
public virtual void Run()
{
Console.WriteLine("RaceCar is running");
}
派生类来重写这个方法,这样增加新类型的时候重写就可以,就不用再更改基类的代码了。但是,如果你觉得这个类中基本不会调用这个Run方法,那我们可以去掉方法体,改成抽象方法,相应的类也变成抽象类,Run完全由派生类来重写。
class Program
{
static void Main(string[] args)
{
Vehicle raceCar = new RaceCar();
Console.ReadKey();
}
}
/// <summary>
/// 交通工具类
/// </summary>
abstract class Vehicle
{
/// <summary>
/// 停车
/// </summary>
public void Stop()
{
Console.WriteLine("Stopped");
}
/// <summary>
/// 加油
/// </summary>
public void Fill()
{
Console.WriteLine("Fill");
}
public abstractvoid Run()
{
Console.WriteLine("RaceCar is running");
}
}
class Car : Vehicle
{
public override void Run()
{
Console.WriteLine("Car is running");
}
}
class RaceCar : Car
{
public override void Run()
{
Console.WriteLine("RaceCar is running");
}
}
4.接口与抽象类
(1)具体类-》抽象类-》接口,越来越抽象,内部实现的类越来越少。
(2)抽象类为复用而生:专门作为基类来使用,也具有解耦功能。
(3)封装确定,开放不确定的,推迟到子类实现。
(4)接口为解耦而生,高内聚,低耦合,方便单元测试。
(5)都不能实例化,只能声明变量,引用具体类的实例。
来源:https://www.cnblogs.com/anjingdian/p/13138430.html


猜你喜欢
- 本文是针对AndBase框架学习整理的第三篇笔记,想要了解AndBase框架的朋友可以阅读本文,大家共同学习。学习内容:1.使用AndBas
- 下面是我的实现经历:1.首先,我是直接使用AlertDialog来实现,确定是,形状有点难看,而且获得Dialog里面的控件略显麻烦(因为我
- boolean isGBK(String s) throws UnsupportedEncodingException { if(s.equ
- 前言在mybatis和mybatis plus里,如果你的实体字段是一个枚举类型,而在数据表里是整型,这时在存储时需要进行处理,默认情况下,
- 我就废话不多说了,大家还是直接看代码吧~<select id="getBiTree" parameterType=
- Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android
- 学过C#的人应该都知道抽象方法与虚拟方法,而很多初学者对二者之间的区别并不是很了解。今天本文就来分析一下二者之间的区别。并附上实例加以说明。
- OSS不支持通过一个网络地址来上传图片,所以若想将网络上的图片上传到OSS上需要走点弯路。1、通过链接将图片下载到本地的一个文件夹下面2、用
- 效果:说明:获取本局域网的MAC地址(非本机的MAC地址)代码:/// <summary>
- 本文实例讲述了Android编程实现网络图片查看器和网页源码查看器。分享给大家供大家参考,具体如下:网络图片查看器清单文加入网络访问权限:&
- 本文实例为大家分享了百度人脸识别之人脸识别FaceIdentify,供大家参考,具体内容如下using System.Collections
- 本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下项目用到的技术点和亮点语音录音 (单个和列表)语音播
- 在实战中学习Spring,本系列的最终目的是完成一个实现用户注册登录功能的项目。预想的基本流程如下:1、用户网站注册,填写用户名、密码、em
- Java 继承与多态的深入理解1、 什么是继承,继承的特点?子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从
- 什么是异常?最简单的,看一个代码示例:public static void main(String[] args) { &nb
- 1. maven项目导入idea报ComponentLookupException异常1.1. 问题描述最近将IDEA 升级到 Intell
- 本文实例讲述了java实现的RSA加密算法。分享给大家供大家参考,具体如下:一、什么是非对称加密1、加密的密钥与加密的密钥不相同,这样的加密
- 上一节我们完成了使用DataGrid显示所有商品信息,这节我们开始添加几个功能:添加、更新、删除和查询。首先我们实现下前台的显示,然后再做后
- // 声明LocationManager对象 LocationManager loctionManager; // 通过系统服务,取得Loc
- 源码:[StructLayout(LayoutKind.Explicit)] public struct IP {&nb