虚方法(virtual)和抽象方法(abstract)的区别

2017年06月15日 13:41:26

阅读数:65

注:本文转载自 http://www.cnblogs.com/michaelxu/archive/2008/04/01/1132633.html

虚方法和抽象方法都可以供派生类重写,它们之间有什么区别呢?

1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。如:

//抽象方法
public abstract class Animal
{
    public abstract void Sleep();
    public abstract void Eat();
}

//虚方法
public class Animal
{
    public virtual void Sleep(){}
    public virtual void Eat(){}
}

2. 抽象方法只能在抽象类中声明,虚方法不是。其实如果类包含抽象方法,那么该类也是抽象的,也必须声明为抽象的。如:

public class Animal
{
    public abstract void Sleep();
    public abstract void Eat();
}

编译器会报错:
Main.cs(10): 'VSTest.Animal.Sleep()' is abstract but it is contained in nonabstract class 'VSTest.Animal'
Main.cs(11): 'VSTest.Animal.Eat()' is abstract but it is contained in nonabstract class 'VSTest.Animal'

3. 抽象方法必须在派生类中重写,这一点跟接口类似,虚方法不必。如:

public abstract class Animal
{
    public abstract void Sleep();
    public abstract void Eat();
}

public class Cat : Animal
{
    public override void Sleep()
    {
        Console.WriteLine( "Cat is sleeping" );
    }
    // we need implement Animal.Eat() here

}

编译器会报错:Main.cs(14): 'VSTest.Cat' does not implement inherited abstract member 'VSTest.Animal.Eat()',因为我们没有实现抽象类中所有抽象方法。

C#中抽象类和接口的区别

大家在编程时都容易把抽象类和接口搞混,下面为大家从概念上讲解抽象类和接口的区别:

一、抽象类:

含有abstract修饰符的class即为抽象类,抽象类是特殊的类,只是不能被实例化,可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖。

二、接口:

接口是引用类型的,类似于类,和抽象类的相似之处有三点:     1、不能实例化;     2、包含未实现的方法声明;     3、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);

    接口有如下特性:

接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。

   两者的语法区别:

1.抽象类可以有构造方法,接口中不能有构造方法。

2.抽象类中可以有普通成员变量,接口中没有普通成员变量

3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

4. 抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

5. 抽象类中可以包含静态方法,接口中不能包含静态方法

6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

7. 一个类可以实现多个接口,但只能继承一个抽象类。

8.接口可以用于支持回调,而继承并不具备这个特点.    9.抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的.

 抽象类和接口的使用:

1.如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。   2.如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口。   3.如果要设计大的功能单元,则使用抽象类.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。   4.抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

5.好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。

虚方法(virtual)和抽象方法(abstract)的和接口(interface)的区别的更多相关文章

  1. [转]虚方法(virtual)和抽象方法(abstract)的区别

    虚方法和抽象方法都可以供派生类重写,它们之间有什么区别呢? 1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化.如: //抽象方法pub ...

  2. 虚方法(virtual)和抽象方法(abstract)的区别

    注:本文转载自 http://www.cnblogs.com/michaelxu/archive/2008/04/01/1132633.html 虚方法和抽象方法都可以供派生类重写,它们之间有什么区别 ...

  3. 虚方法virtual、抽象方法abstract、接口interface区别

    接口.抽象类.抽象方法.虚方法: 这四个名词时非常容易混淆的: 首先说一下接口 与抽象类 的异同: 相同点: 1.他们都不能实例化自己,也就是说都是用来被继承的. 2.抽象类中的抽象方法和接口方法一样 ...

  4. 抽象方法(abstract method) 和 虚方法 (virtual method), 重载(overload) 和 重写(override)的区别于联系

    1. 抽象方法 (abstract method) 在抽象类中,可以存在没有实现的方法,只是该方法必须声明为abstract抽象方法. 在继承此抽象类的类中,通过给方法加上override关键字来实现 ...

  5. Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息

    Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...

  6. C#虚方法virtual详解

    转: http://www.cnblogs.com/jason_yjau/archive/2009/08/25/1553949.html C#虚方法virtual详解 在C++.Java等众多OOP语 ...

  7. 4.C#虚方法virtual详解

    C#虚方法virtual详解 在C++.Java等众多OOP语言里都可以看到virtual的身影,而C#作为一个完全面向对象的语言当然也不例外. 虚拟函数从C#的程序编译的角度来看,它和其它一般的函数 ...

  8. 虚方法virtual详解

    虚方法virtual详解   从C#的程序编译的角度来看,它和其它一般的函数有什么区别呢?一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,也就是写死了的!而虚函数在 ...

  9. 虚方法(virtual)

    虚方法(virtual) Virtual 关键字用于修饰方法.属性.索引器或事件声明,并且允许在派生类中重写这些对象. 看一段代码: using System ; class A { public v ...

随机推荐

  1. 浏览器端时间循环与nodejs端时间循环的不同之处(宏任务与微任务)

    浏览器端与node端都有宏任务与微任务的概念.字面意思上看宏任务就是耗时间比较长的任务,而微任务是耗时短的任务. 在浏览器端,宏任务包括setTimeout,setInterval,微任务则包括Pro ...

  2. JS stacktrace(Node内存溢出)

    vscode运行项目时,保存.vue文件,项目突然终止运行.输入命令npm run dev重新运行后,终端显示下面的错误. 解决方案: 如果是run dev时报错,在package.json文件里的s ...

  3. Android Spannable为同一TextView设直不同样式

    /** * UNICODE * <p> * 偶尔吃(1-2次/周) ( 中文破弧 * 经常吃(3-5次/周) ( 英文破弧 * * @param name * @return */ pri ...

  4. OGRE

    [编译 OGRE C#] 1.官网下载 OGRE 源码. 2.打开CMake,指定好OGRE目录,以及生成目标目录. 3.将 CMake/Modules 目录下的 FindSwig.cmake 中的 ...

  5. docker学习-常用命令2

    三.容器管理命令3.1 Docker commit 命令,从容器创建一个新的镜像.OPTIONS说明: -a :提交的镜像作者: -c :使用Dockerfile指令来创建镜像: -m :提交时的说明 ...

  6. PhoenixFD插件流体模拟——UI布局【Preview】详解

    Liquid Preview 流体预览  本文主要讲解Preview折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Pr ...

  7. Windows下phpstudy配置tp5的nginx时遇到的奇葩问题

    nginx原来的配置: hosts已经配置好127.0.0.1 到tpdev1.net这个域名 最后结果 No input file specified. 解决方法: 找到原因了,竟然是root的分隔 ...

  8. Linux - 文件和目录常用命令

    文件和目录常用命令 目标 查看目录内容 ls 切换目录 cd 创建和删除操作 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 ...

  9. Handling Text in Python 相关命令

    s.isalpha()意思就是是不是字母,s.isdigit()意思就是是不是0-9,s.isalnum()意思就是是不是由字母和数字组成.

  10. 阅读:JAVA 3& 4

    随机数: Random rand = new Random(47); // 产生随机算子.47 is seed. for incovating predicatable random numberin ...