C# abstract抽象类的定义,作用(使用场景)

写代码已经有很长一段时间, 但感觉成长很少,基本是为了功能开发而开发,我相信80%的程序员都一样,基本都是拿网上的开源项目改改改后实现功能就行, 很少会去深入,去思考为什么要这么来实现,所以有了今天的文章,我作为程序员小白鼠把C#中的抽象类学习中的感想跟大家分享一下:


什么是抽象类

抽象类的应用场景

实例代码

1.什么是抽象类

我先来个百度百科的词条解释吧


抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象`

c#中的抽象类的特征


抽象类不能实例化。

抽象类可以包含抽象方法和抽象访问器。

不能用 sealed 修饰符修饰抽象类,因为这两个修饰符的含义是相反的。 采用 sealed 修饰符的类无法继 承,而 abstract 修饰符要求对类进行继承。

从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实际实现。

其实这些都是废话,我感觉一点都理解不了,我觉得用简单的话来说抽象类的功能就是:我是老子(抽象类),你要是跟了(继承)老子,你就必须得会干什么(实际实现) 

举个场景就是:老子会打人,那你也必须会打人,但你是轻轻的打,还是狠狠的打,你自己决定,但你必须得会打人。


抽象类的应用场景

如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧


实例代码

1.先建一个BaseClass的抽象类,例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace absract_learn
{
   public abstract class BaseClass
    {
        public abstract void Eat(); // 抽象方法-吃饭
        public abstract void Walk(); // 抽象方法-走路
        public abstract void Speak(); // 抽象方法-说话
    }
}

2.建一个human的普通类继承抽象类,例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace absract_learn
{
    public class human : BaseClass
    {
        public void Eat()//实现吃饭
        {
            Console.WriteLine("I can eat");
        }
 
        public void Walk()//实现走路
        {
            Console.WriteLine("I can walk");
        }
 
        public void Speak()//实现说话
        {
            Console.WriteLine("I can speak");
        }  
 
    }
}


那么我们什么时候应该用抽象类呢?

如果一个类设计的目点是用来被其它类继承的,它代表一类对象的所具有的公共属性或方法,那个这个类就应该设置为抽象类。


我觉得用简单的话来说抽象类的功能就是:我是老子(抽象类),你要是跟了(继承)老子,你就必须得会干什么(实际实现) 

举个场景就是:老子会打人,那你也必须会打人,但你是轻轻的打,还是狠狠的打,你自己决定,但你必须得会打人。


如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧


抽象类与其它的类有什么区别呢?

抽象类是不能够被实例化的。如果一个类中包含有抽象方法,那么这个类一定要声明为抽象类。同时,抽象方法一定需要在子类中重写,让抽象方法成为一个具体的实实在在的方法。


相信大家在网上一定看过很多这类解释了吧?好吧,不理解的我们一起来看看通俗易理解的说法吧:


比如说:我们需要创建 “狗”、“猫”、“鱼”、“马”这些对象(类),我们可以说他们有一些共同的属性像嘴巴、尾巴、重量、颜色、大小等等一些共同的属性(properties),但是它们彼此的属性的形状是不同的(如嘴巴),在这种情况下,我们如果一个个去定义各自类似的属性是不是比较繁琐?如果用抽象类是不是很方便的给他们去继承。抽象类也有个更加好的地方,体现在“同质异像”就是实质相同实现形式不同的方法继承上,例如上面的狗、猫、马等的呼吸这个方法或者跑的速度的方法形式不同,我们这个是用定义一个抽象方法,让他们各自的类去实现它是不是很方便。“抽象”的意义正在于此。将共同的东西抽出来封装,但不实现只给继承。


凡是包含抽象方法的类都是抽象类,此时,必须加abstract关键字:

抽象类中不必非得包含抽象方法,此时,向抽象类中添加的方法只能是静态方法

抽象类不能实例化,但仍然可以具有构造方法

在实现抽象类时,子类必须实现抽象类中声明的抽象方法

抽象类可以包含非抽象的方法

继承的子类没实现其中所有的抽象方法,那么这个子类也是抽象类

抽象方法也是虚拟的,但是不需要提供关键字virtual

抽象类不能使用new关键字,不能被密封


在抽象方法声明中不能使用static或virtual修饰符

我们知道,接口可以包含方法的申明和属性,但是方法中不包含代码,实现这个接口的方法必须包含接口中的所有方法和属性,但是现在出现这种情况,假设需要一个“接口”,要求类实现某些方法和属性,但是需要这这个“接口”中包含一些代码,从而不必在每个派生类中重复地实现某些方法,对于这种情况,你需要的不是接口,而是一个抽象类(abstract class)。


按照定义,抽象类和一般的类有异同,和接口也有异同。下面笔者将一一为您揭晓。


一、抽象类和一般类的相同点:都可以继承其他的类或者接口,也可以派生子类,并且都有具体的方法;

不同点:抽象类中有抽象方法,一般类中没有;抽象类不可以实例化,一般类却可以;

二、抽象类和接口的相同点:都不能实例化,继承抽象类的子类必须实现抽象类中的抽象方法,实现接口的子类必须实现接口中的全部方法和属性。


不同点:抽象类中除了具有抽象方法之外,还有具体的方法。

抽象类与一般类、接口在代码表示上有所不同:


1、抽象类:abstract class class_abstract_name;

2、一般类:class class_name;

3、接口:interface interface_name;

4、抽象方法:abstract public void test();或者public abstract void test();//抽象方法中必须使用public修饰符。

5、一般方法:public/private/protected/.. void/string/int/... method_name();

6、父类中的虚拟方法:public virtual void test_1();或者virtual public void test_1();//虚拟方法必须使用public修饰符。

7、子类中实现父类的虚拟方法或抽象方法:public override void test_1();或者override public void test_1();


注意:只有抽象类可以有抽象方法,不过抽象类可以有具体方法。如果把一个抽象方法放在一个类中,就必须标识这个类为抽象类。

 

抽象类一般用于表达比较抽象的事物,如:“宠物”,它并不是一个实实在在存在的东西,而是一些小动物的代称,是抽象的。而抽象方法则说明这种抽象事物有某种特性,但是当抽象事物具体到某一种实物的实物,不同的个体的这种特性又不同,如狗和猫的叫声不同。因此,把狗和猫叫的这种动作定义为一种抽象方法。


抽象类定义:在类的前面加上Abstract 关键字,则此类为抽象类。 

如: public abstract class Pet 

在抽象类中既可以包含抽象方法又可以包含普通方法,但普通方法只能在派生类的对象中去调用,不能直接实例化抽象类。抽象类不能被密封。 

抽象类可以被抽象类所继承,结果仍是抽象类。


抽象方法定义:带有abstract关键字的方法为抽象方法 

抽象方法不能有函数体,只能是定义,不能包含具体实现,抽象类不能被实例化,只能被继承,定义的抽象方法只能在派生类中进行override重写,才能实现具体逻辑。


抽象类和接口的区别 

.它们的派生类只能继承一个基类,即只能继承一个抽象类,但是可以继承多个接口。 

·抽象类中可以定义成员的实现,但接口中不可以。 

·抽象类中包含字段、构造函数、析构函数、静态成员或常量等,接口中不可以。 

·抽象类中的成员可以私有的(只要不是抽象的)、受保护的、内部的或受保护的内部成员,但接口中的成员必须是公共的。

密封类:

密封类是指用sealed关键字定义的类,密封方法是指用sealed关键字定义的方法,如果比希望类被继承或者方法被再重写,则将类或方法定义为密封的即可

其实很多人都会像我一样,看这样的代码感觉在脱裤子放屁,我直接创建方法也一样的实现啊,但是优秀的人做的优秀的方法肯定是有他的道理的,而且编程真的不能只看不写,强迫自己按照这样的模式来写,慢慢的你也就变成优秀的人了。



再来总结一下抽象类和接口的特点:


抽象类:

① 不可以实例化

② 可以包含抽象方法和抽象访问器

③ 不可以用sealed修饰符修饰,因为和abstract修饰符是相反的。sealed修饰的类不能继承,而abstract修饰的类可以继承

④ 继承该类的类必须把里面的抽象成员全部重写。除非是抽象类


接口:

① 不可以实例化

② 支持多继承

③ 只能定义行为

④ 只包含方法、属性、索引器和事件的签名。方法的实现是在实现接口的类中完成的


接口和类的异同点


不同点:

① 不能化接口

② 接口没有方法的实现

③ 接口可以多继承,但是类只能单继承

④ 类定义可以在不同的源文件之间进行拆分


相同点:

① 接口和类还有接口都可以从多个接口继承

② 接口类似于抽象类:继承接口的任何非抽象类型都必须实现接口的所有成员

③ 接口和类都可以包含事件、索引器、方法和属性

在这里插入图片描述

1.抽象类是提取具体类的公因式,而接口是为了将一些不相关的类“杂凑”成一个共同的群体。
2.所有代码共有和可扩展性考虑,尽量使用Abstract Class。
3.当在差异较大的对象间寻求功能上的共性时,使用接口;当共性较多的对象间寻求功能上的差异时,使用抽象类。
4.如果要创建组件的多个版本,建议使用抽象类。如果设计小而简练的功能块,则使用接口。

另见网上举得比较好的几个例子:

举例:

1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。

2. 就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口)也可以有门铃(多实现)。 门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音吧(接口污染))。



--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!

本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864