这几天正在做GDI+的一个练习程序,参考了《VC#.NET开发交互式CAD系统》这本书,书中的参考方法创建了许许多多的类和一个接口。开始我还在想接口有啥作用啊?是不是有点多此一举。然后就去网上搜索了一下接口的意义,个人感觉受益颇多,顺便把以前搜索过的内容翻出来记录总结一下。

我相信一定有很多和我一样的同学,对接口、虚方法、抽象类感觉很模糊、很生疏。这些东西用起来好像很简单,定义接口,里面包含方法,但没有方法具体实现的代码,然后在继承该接口的类里面要实现接口的所有方法的代码。

我在网上看到了一个简单易懂的例子:

首先,我们先定义一个接口:(接口的关键字interface)

public interface IBark
{void Bark();
}

再定义一个类,继承于IBark,并且必需实现其中的Bark()方法

public class Dog:IBark
{public Dog(){}public void Bark(){Consol.write("汪汪");}
}

Dog的一个实例,并调用Bark()方法

Dog 旺财=new Dog();
旺财.Bark();

试想一样:
       若是想调用Bark()方法,只需要在Dog()中声明这样的一个方法不就行了吗,干什么还要用接口呢?
       因为接口中并没有Bark()具体实现.真的实现还是要在Dog()中.那么使用接口不是多此一举吗?

我做练习是就是这样想的,代码如下。究竟是为啥呢?

还有人是这样说的:从接口的定义方面来说,接口其实就是类和类之间的一种协定,一种约束.还拿构会叫的例子来说.所有继承了IBark接口的类中必需实现Bark()方法.那么从用户(使用类的用户)的角度来说,如果他知道了某个类是继承于IBark接口,那么他就可以放心大胆的调用Bark()方法,而不用管Bark()方法具体是如何实现的.比如,我们另外写了一个类。

public class Cat:IBark
{public Cat(){}public void Bark(){Consol.write("喵喵");}
}

当用户用到Cat类或是Dog类的时候,知道他们继承于IBark,那么不用管类里的具体实现,而就可以直接调用Bark()方法,因为这两个类中肯定有关于Bark()方法的具体实现.

如果我们从设计的角度来看.一个项目中用若干个类需要去编写,由于这些类比较复杂,工作量比较大,这样每个类就需要占用一个工作人员进行编写.比如A程序员去定Dog类,B程序员去写Cat类.

这两个类本来没什么联系的,可是由于用户需要他们都实现一个关于”叫”的方法.

这就要对他们进行一种约束,让他们都继承于IBark接口。

说了这么多,其目的就是统一管理,再者就是方便他人调用,再加上就是避免有些人会漏掉这个方法。(漏掉就会报错哦,我就是刚开始一直纳闷为啥这报错了)

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

再者就是虚方法:

当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法,虚方法是使用关键字virtual声明的,虚方法可以在不同的继承类中有不同的实现,即为基类中定义的允许在派生类中重写的方法。

访问修饰符 virtual 返回值类型 函数名(参数)
{函数体;
}

调用上,使用子类构造的对象调用虚方法,就会调用子类的方法,使用父类构造的对象,就会调用父类的方法

1、在基类中声明的虚方法一般在派生类中对其进行调用,会运用到base关键字

(当输入访问修饰符和override后,系统会自己弹出我们刚才编写的虚方法,直接进行选择即可)

class Person
{public virtual void XXX()// 虚方法是在方法前加virtual关键字,对方法进行声明{Console.Write("Hello World");}
}class Boy:Person
{public override void XXX()//虚方法调用{base.XXX();...}
}
//在运行时调用
static void Main(string[] args)
{Person person = new Person();//虚拟类其实指的是正常类中的虚拟方法,所以虚拟类可以直接使用实例,这是与抽象类不同的一点,它不会像抽象类一样进行报错!!!   Boy boy = new Boy();boy.XXX();//Hello World
}

这里注明三点

1、虚拟函数和正常函数无区别。

2、当用virtual修饰后,不允许再有 staticabstract 或者 override 修饰符。

3、子类继承虚拟类可以实现虚拟方法也可以不实现虚拟方法,如下例子:

class Person{public virtual void XXX(){Console.WriteLine("我有一千万给你!");}}class Boy : Person{public override void XXX(){Console.WriteLine("我不要你的钱");}public void YYY(){Console.WriteLine("我自己要努力,自己挣钱");}}class Program{static void Main(string[] args){Person person = new Person();//实例化的虚方法类Boy boy = new Boy();//实例化的子类。记得实例化!千万不能忘记哟boy.XXX();//调用了子类的方法boy.YYY();Console.ReadLine();}}
//结果: 我不要你的钱我自己要努力,自己挣钱

总结一下虚方法的作用:1、增加code的可维护性,脉络清晰、有条理。2、允许 子类 进行重写。

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

最后是抽象类

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

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

我们还以猫和狗为例子,假如我们不单单有猫和狗,还有鲨鱼、蚯蚓、猫头鹰等,他们有一个共性:是动物animal

animal仅仅是一个词而已,他不代表任何的具体对象,它只是代表所有动物所拥有的共同特征,所以animal类是根本不可能被实例化的。

同时,如果所有动物都必须声明"叫"这样一个方法的话,那么,我们可以在animal类中声明一个抽象方法bark(),因为抽象方法是必须在子类中重写的,所以这就限制了所有继承自animal类都必须重写bark()方法。

abstract class Animal //声明Animal为抽象类
{protected abstract void Bark(); //声明Shout()方法为抽象方法,那么所有继承Animal类的子类都必须重写Bark()方法
}//声明Dog类,继承自Animal类class Dog:Animal
{protected override vod Bark(){response.write("woof woof");}
}

一个抽象类可以包含抽象和非抽象方法,当一个类继承于抽象类,那么这个派生类必须实现所有的基类抽象方法

一个抽象方法是一个没有方法体的方法。

//拾取图元
abstract public bool Pick(PointF aPos);//平移图元
abstract public void Move(Graphics g, PointF basePos, PointF desPos);
  • 抽象方法有以下特征:

1.一个抽象方法可以看作是一个虚函数。

2.抽象方法的声明只能在抽象类中。

3.因为抽象方法声明只提供一个无实现的方式,没有方法体

4.方法体的实现被覆写方法提供,覆写方法是一个非抽象类的成员。

5.抽象属性的行为和抽象方法相像,除了不同的声明形式。//一个抽象属性能够通过派生类使用 override 实现

6.在一个静态属性中使用abstract 是一个错误。

  • 抽象类具有以下特征:

1.抽象类不能被实例化。

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

3.不能把抽象类用密封(sealed)来修饰,那就意味着类不能被继承,这违反抽象类被继承的原则。

4.一个派生于一个抽象类的非抽象类必须包括所有的继承来的抽象方法和访问器的实现

5.在方法和属性中使用abstract 关键字意味着包含它们的实现。

C# 多态(接口、虚方法、抽象类)的理解相关推荐

  1. C# 中的多态和虚方法,如何实现多态和使用虚方法?

    在 C# 中,多态(Polymorphism)是面向对象编程的基本特性之一,它允许使用不同的对象和方法来执行同一操作.C# 中实现多态的方式主要是通过虚方法和抽象类. 虚方法是一种允许子类覆盖的方法, ...

  2. 多态的实现(重载,虚方法,抽象类,接口)

    1.前言 多态是指,在同一个方法中,由于参数不同而导致执行效果各异.多态的实现方式主要是通过函数.运算符重载,虚成员,以及抽象类实现和接口.下面的内容就详细介绍一下前三种多态的实现形式. 2.方法重载 ...

  3. 【原创】SystemVerilog中的多态和虚方法

    封装可以隐藏实现细节,使代码模块化,继承可以扩展已经存在的代码模块,目的都是为了代码重用.多态是为了实现接口的重用.在SystemVerilog中,子类和父类之间多个子程序使用同一个名字的现象称为Sy ...

  4. java的虚方法_Java多态和虚方法调用

    多态(polymorphism) 多态的概念 ·多态是指一个程序中相同的名字表示不同的含义的情况. ·多态有两种情形: 1.编译时多态: 1.重载(overload)多个同名的不同方法: 2.如:p. ...

  5. C++多态中虚函数的深入理解

    c++中动态多态性是通过虚函数来实现的.静态多态性是通过函数的重载来实现的,在程序运行前的一种早绑定,动态多态性则是程序运行过程中的一种后绑定.根据下面的例子进行说明. #include <io ...

  6. C#-继承-多态-VIRTUAL虚方法(下)

    面向对象的编程中,有着一个叫做"依赖倒置原则" 程序设计要依赖与抽象类,而不依赖于具体类 比如说抽象类就相当于是父类"宠物" 具体类就是"狗狗&quo ...

  7. C#继承与多态 virtual虚方法的使用 在子类中使用override重写父类函数

    本片文章讲的是多态 子类重写父类函数的方式如下:在父类函数使用virtual,在子类函数中使用override 注意定义变量的时候要使用new来创建,而不要使用类名 变量名的方式,否则在使用时会报错& ...

  8. [转载]CLR怎样实现虚方法的多态调用(2)

    本文转载自:http://www.cnblogs.com/blusehuang/archive/2007/08/03/841707.html 在上一篇文章CLR怎样实现虚方法的多态调用(1)中主要介绍 ...

  9. c# 多态实现_虚方法

    实现方法: 虚方法, 抽象类, 接口 1.虚方法 将父类的方法标记为虚方法,使用关键字virtual,这个方法可以被子类重新写一遍. 在父类的方法前面加上一个virtual,在子类的方法前面加上一个o ...

  10. C++ day22 继承(二)基类指针数组通过虚方法实现智能的多态

    继承一共有三种: 公有继承 私有继承 保护继承 文章目录 公有继承 基类和派生类的关系 is-a(用公有继承表示"是一种"的关系) has-a uses-a is-like-a i ...

最新文章

  1. 2021年春季学期-信号与系统-第二次作业参考答案-第七小题
  2. python是基于什么语言开发-2.python是什么编程语言。
  3. Mysql 於lampp xampp LinuxUbuntu下的配置
  4. 为你的程序添加监听器
  5. 你有关注自己的简历吗?优秀的程序员简历是怎样炼成的?
  6. Scala是多范式编程语言
  7. 蓝桥杯2016年第七届C/C++省赛B组第三题-凑算式
  8. LINUX模拟键盘F5的脚本(未试过)
  9. RFC822邮件格式
  10. (2021总结篇)面向对象软件设计模式--(八)结构型模式---树形结构的处理--组合模式
  11. 30岁学linux内核,明尼苏达大学Linux内核“伪装者提交”研究人员发表公开信
  12. 用小马激活的千万小心!!
  13. 删除OneDrive右键菜单
  14. Virtualbox-Ubuntu与主机(WIN7)共享文件夹设置
  15. 海康威视API-单帧数据捕获并保存成JPEG图片NET_DVR_CaptureJPEGPicture
  16. springboot游泳池管理系统
  17. return返回值用法
  18. Blender Rigify版Walker绑定下载
  19. java 体检套餐_第五章项目:体检套餐
  20. linux定时器crontab的使用

热门文章

  1. “由于/bin 不在PATH 环境变量中,故无法找到该命令”
  2. 笔记本右侧手滑板Synaptics
  3. python类的参数传递
  4. 人人都能看懂LSTM
  5. 命令行操作svn和git和git
  6. 基于CORS的geoserver同源访问策略
  7. CMake手册详解 (十二)
  8. xmpp这一段蛋疼的 坑,
  9. JavaScript求当月天数
  10. EqualLogic全攻略视频[(一)介绍]