C#中Abstract 、Virtual和Override的使用及区别

1. abstract 修饰符指示所修饰的内容缺少实现或未完全实现。abstract修饰符可用于类、方法、属性、索引器和事件。在类声明中使用abstract修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。

(1)抽象类具有以下特性:

1) 抽象类不能实例化。

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

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

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

5) 在方法或属性声明中使用abstract修饰符以指示方法或属性不包含实现。

(2)抽象方法具有以下特性:

1) 抽象方法是隐式的虚方法。

2) 只允许在抽象类中使用抽象方法声明。

3) 因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号({ })。

(3)在抽象方法声明中使用static或virtual修饰符是错误的。除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。在静态属性上使用abstract修饰符是错误的。在派生类中,通过包括使用override修饰符的属性声明,可以重写抽象的继承属性。

publicabstractclassparent

{

protectedintx=100;

protectedinty = 200;

publicabstractvoidfunction();

publicabstractintX {get; }

publicabstractintY {get; }

}

publicclassnewperson:parent

{

publicoverridevoidfunction()

{

x++;

y++;

}

publicoverrideintX

{

get{returnx+100; }

}

publicoverrideintY

{

get{returny+100; }

}

}

staticvoidMain(string[] args)

{

newpersonp =newnewperson();

Console.WriteLine(p.X);

Console.WriteLine(p.Y);

p.function();

Console.WriteLine(p.X);

Console.WriteLine(p.Y);

Console.ReadKey();

}

2.virtual关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。虚拟成员的实现可由派生类中的重写成员更改。调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。默认情况下,方法是非虚拟的。不能重写非虚方法。virtual修饰符不能与static、abstract, private或override修饰符一起使用。和抽象方法的相同点是都用了override关键字进行重写方法,不同点是抽象方法必须存在于抽象类中,而子类必须重写,除非子类也是抽象的。

publicclassDimensions

{

publicconstdoublePI =Math.PI;

protecteddoublex;

protecteddoubley;

publicDimensions() { }

publicDimensions(doublex,doubley)

{

this.x = x;

this.y = y;

}

publicvirtualdoubleArea()

{

returnx * y;

}

}

publicclassCircle:Dimensions

{

publicCircle(doubler) :base(r,0) { }

publicoverridedoubleArea()

{

Console.WriteLine(base.Area());

returnPI * x * x;

}

}

publicclassSphere:Dimensions

{

publicSphere(doubler) :base(r,0) { }

publicoverridedoubleArea()

{

return4 * PI * x * x;

}

}

publicclassCylinder:Dimensions

{

publicCylinder(doubler,doubleh) :base(r, h) { }

publicoverridedoubleArea()

{

return2 * PI * x * x + 2 * PI * x * y;

}

}

staticvoidMain(string[] args)

{

DimensionsP =newCircle(5.0);

Spheresphere =newSphere(10);

Cylindercylinder =newCylinder(10, 10);

Console.WriteLine(P.Area());

Console.WriteLine(sphere.Area());

Console.WriteLine(cylinder.Area());

Console.ReadKey();

}

3.override方法提供从基类继承的成员的新实现。由override声明重写的方法称为重写基方法。重写的基方法必须与override方法具有相同的签名。不能重写非虚方法或静态方法。重写的基方法必须是virtual、abstract或override的。override声明不能更改virtual方法的可访问性。override方法和virtual方法必须具有相同的访问级别修饰符。重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须是virtual、abstract或override的。

4.base和this的区别

1)base作用:用于从派生类中访问基类的成员,调用基类上已被其他方法重写的方法。指定创建派生类实例时应调用的基类构造函数。

注:从静态方法中使用base关键字是错误的。
2)区别:

base是子类中引用父类,用于在派生类中访问重写的基类成员。
this是当前类,引用自己,用于访问本类的成员,当然也包括继承而来公有和保护成员。

3)注意:
a).在静态成员中使用base和this都是不允许的。原因是,base和this访问的都是类的实例,也就是对象,而静态成员只能由类来访问,不能由对象来访问。
b).base是为了实现多态而设计的。
c).使用this或base关键字只能指定一个构造函数,也就是说不可同时将this和base作用在一个构造函数上。
d).除了base,访问基类成员的另外一种方式是:显示的类型转换来实现。只是该方法不能为静态方法。

以上就是C#中Abstract 、Virtual和Override的使用及区别的详细内容,更多关于C# Abstract 、Virtual和Override使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • 深入理解C#中new、override、virtual关键字的区别

    OO思想现在已经在软件开发项目中广泛应用,其中最重要的一个特性就是继承,最近偶简单的复习了下在C#中涉及到继承这个特性时,所需要用到的关键字,其中有一些关键点,特地整理出来,方便大家查阅. 一.在C#中,new这个关键字使用频率非常高,主要有3个功能: a) 作为运算符用来创建一个对象和调用构造函数. b) 作为修饰符. c) 用于在泛型声明中约束可能用作类型参数的参数的类型. 在本文中,只具体介绍new作为修饰符的作用,在用作修饰符时,new关键字可以在派生类中隐藏基类的方法,也就说在使用派生

  • C# new和override的区别分析

    昨天面试问到了new的几种用法以及与Override的区别,有点模糊 回来google下,new的用法有以下3中 1.运算符:初始化对象和调用构造函数 2.修饰符:隐藏基类方法 3.于在泛型声明中约束可能用作类型参数的参数的类型 至于作为修饰符和override的区别,看了下文章不太明白,写了个例子,运行结果,发现了差异,下面分享下代码: using System; using System.Collections.Generic; using System.Linq; using System

  • C#中Override关键字和New关键字的用法详解

    C# 语言经过专门设计,以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容.这具有多方面的意义.例如,这意味着在基类中引入与派生类中的某个成员具有相同名称的新成员在 C# 中是完全支持的,不会导致意外行为.它还意味着类必须显式声明某方法是要重写一个继承方法,还是一个隐藏具有类似名称的继承方法的新方法. 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtual. 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警

  • 深入理解C# abstract和virtual关键字

    复制代码 代码如下: class A { public virtual void Func() // 注意virtual,表明这是一个虚拟函数 { Console.WriteLine("Func In A"); } } class B : A // 注意B是从A类继承,所以A是父类,B是子类 { public override void Func() // 注意override ,表明重新实现了虚函数 { Console.WriteLine("Func In B")

  • 深入解析C#中的abstract抽象类

    抽象类和类成员 通过在类定义前面放置关键字 abstract,可以将类声明为抽象类.例如: public abstract class A { // Class members here. } 抽象类不能实例化.抽象类的用途是提供一个可供多个派生类共享的通用基类定义.例如,类库可以定义一个抽象类,将其用作多个类库函数的参数,并要求使用该库的程序员通过创建派生类来提供自己的类实现. 抽象类也可以定义抽象方法.方法是将关键字 abstract 添加到方法的返回类型的前面.例如: public abs

  • c#中的interface abstract与virtual介绍

    interface用来声明接口1.只提供一些方法规约,不提供方法主体.  如: 复制代码 代码如下: public interface IPerson{    void getName();//不包含方法主体} 2.方法不能用public abstract等修饰,无字段变量,无构造函数.3.方法可包含参数.  如 复制代码 代码如下: public interface IPerson  {    void getAge(string s);  } 一个例子(例1): 复制代码 代码如下: pub

  • C#中abstract的用法详解

    abstract可以用来修饰类,方法,属性,索引器和时间,这里不包括字段. 使用abstrac修饰的类,该类只能作为其他类的基类,不能实例化,而且abstract修饰的成员在派生类中必须全部实现,不允许部分实现,否则编译异常. 如: using System; namespace ConsoleApplication8 { class Program { static void Main(string[] args) { BClass b = new BClass(); b.m1(); } }

  • C#中Abstract 、Virtual和Override的使用及区别

    1. abstract 修饰符指示所修饰的内容缺少实现或未完全实现.abstract修饰符可用于类.方法.属性.索引器和事件.在类声明中使用abstract修饰符以指示某个类只能是其他类的基类.标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现. (1)抽象类具有以下特性: 1) 抽象类不能实例化. 2) 抽象类可以包含抽象方法和抽象访问器. 3) 不能用sealed修饰符修饰抽象类,因为这两个修饰符的含义是相反的.采用sealed修饰符的类无法继承,而abstract修饰符要求对类

  • C#中Abstract方法和Virtual方法的区别

    简介: c#中Abstract和Virtual比较容易混淆,都与继承有关,并且涉及override的使用.virtual可以被子类重写,而abstract必须被子类重写.virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不能实现.它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的.毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的.下面

  • C++中Overload,Override,Hide之间的区别

    一. 简介•Overload: 重载,指函数同名,但是参数个数不同.或者参数类型不同的多个实现.(如果参数相同但是仅仅返回值不同不是重载,编译器会报错.) 编译器判断重载函数:•第一步,是确定该调用中所考虑的重载函数的集合,该函数集合被称为候选函数(candidant function).所谓候选函数就是与被调用函数同名的函数. •第二步,分为两动作:第一个动作是编译器从第一步选出的候选函数中调出可行函数(viable function).可行函数的函数参数个数与调用的函数参数个数相同,或者可行

  • PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解

    本文实例讲述了PHP中abstract(抽象).final(最终)和static(静态)原理与用法.分享给大家供大家参考,具体如下: abstract(抽象) PHP 5 支持抽象类和抽象方法.定义为抽象的类不能被实例化.任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的.被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现. 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法:另外,这些方法的访问控制必须和父类中一样(或者更为宽松).例

  • JVM系列之:JIT中的Virtual Call接口操作

    简介 上一篇文章我们讲解了Virtual Call的定义并举例分析了Virtual Call在父类和子类中的优化. JIT对类可以进行优化,那么对于interface可不可以做同样的优化么? 一起来看看吧. 最常用的接口List List应该是大家最最常用的接口了,我想这个大家应该不会反驳. public interface List<E> extends Collection<E> { 今天我们就拿List来做例子,体验一下JIT优化接口的奥秘. 还是上代码,要分析的代码如下:

  • java中abstract修改类的实例方法

    abstract是一种修饰类,经过修改的类会变成抽象类.除了类之外还可以修改方法,考虑到类的模块是小伙伴们常接触的,今天来小编带大家一起找寻使用abstract修改类的方法.这里需要我们先从abstract丁酉.特点.方法.注释进行学习,然后在实例中体会修改类的用法. 1.abstract定义 abstract关键字可以修改类或方法. abstract 类可以扩展(增加子类),但不能直接实例化. abstract 方法不在声明它的类中实现,但必须在某个子类中重写. 2.特点 可以声明引用不能创建

  • Spring中的注解之@Override和@Autowired

    一.Override 首先,@Override 注解是伪代码,表示子类重写父类的方法.这个注解不写也是可以的,但是写了有如下好处: 1. 可以当注释用,方便阅读(注解很重要的一个作用就是注释): 2. 编译器和 IDE 可以验证 @Override 下面的方法名是否是父类中所有的,如果没有的话就会报错.如果没有加 @Override ,而子类中的方法名又写错了,这个时候编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法. 下面来验证一下,首先有一个 IPay 的父类,包含一

  • 浅谈JVM系列之JIT中的Virtual Call

    Virtual Call和它的本质 有用过PrintAssembly的朋友,可能会在反编译的汇编代码中发现有些方法调用的说明是invokevirtual,实际上这个invokevirtual就是Virtual Call. Virtual Call是什么呢? 面向对象的编程语言基本上都支持方法的重写,我们考虑下面的情况: private static class CustObj { public void methodCall() { if(System.currentTimeMillis()==

  • Android中Handler、Thread、HandlerThread三者的区别

    目录 一.前期知识储备 二.三者的区别 三.HandlerThread的使用 一.前期知识储备 (1)Handler类,上官方文档,Handler public class Handler.A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a s

随机推荐