C#中的abstract与virtual
2008-03-14 14:01

【abstract】
abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。
在类声明中使用 abstract 修饰符以指示类只能是其他类的基类。

抽象类具有以下特性:
·抽象类不能实例化。
·抽象类可以包含抽象方法和抽象访问器。
·不能用 sealed 修饰符修改抽象类,这意味着该类不能被继承。
·从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
·在方法或属性声明中使用 abstract 修饰符以指示此方法或属性不包含实现。

抽象方法具有以下特性:
·抽象方法是隐式的 virtual 方法。
·只允许在抽象类中使用抽象方法声明。
·因为抽象方法声明不提供实实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如: public abstract void MyMethod();
·实现由 overriding 方法提供,它是非抽象类的成员。
·在抽象方法声明中使用 static 或 virtual 修饰符是错误的。

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

【virtual】
virtual 关键字用于修改方法或属性的声明,在这种情况下,方法或属性被称作虚拟成员。虚拟成员的实现可由派生类中的重写成员更改。

调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。

默认情况下,方法是非虚拟的。不能重写非虚方法。

不能将 virtual 修饰符与以下修饰符一起使用:
static   abstract   override

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

【override】 (覆盖上面两种关键字修饰方法)
使用 override 修饰符来修改方法、属性、索引器或事件。重写方法提供从基类继承的成员的新实现。由重写声明重写的方法称为重写基方法。重写基方法必须与重写方法具有相同的签名。

不能重写非虚方法或静态方法。重写基方法必须是虚拟的、抽象的或重写的。
重写声明不能更改虚方法的可访问性。重写方法和虚方法必须具有相同的访问级修饰符。
不能使用下列修饰符修改重写方法:
new   static    virtual   abstract
重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或重写的。
using System;

namespace VitualMethod
{
    class BeiseClass
    {
        public void RealMethod()
        {
            Console.WriteLine(@"The ""RealMethod"" method of ""BeiseClass"" class!");
        }

public virtual void ViutualMethod()
        {
            Console.WriteLine(@"The ""ViutualMethod"" method of ""BeiseClass""class!");
        }
    }

class NewAndOverride: BeiseClass
    {
        /// <summary>
        /// “new”用于隐藏基类成员的继承成员,是重写方法的另一种办法;
        /// 在同一成员上同时使用 new 和 override 是错误的;
        /// “override”是覆盖了虚拟方法。
        /// </summary>
        new public void RealMethod()
        {
            Console.WriteLine(@"The ""RealMethod"" method of ""NewAndOverride"" class!");
        }

public override void ViutualMethod()
        {
            Console.WriteLine(@"The ""ViutualMethod"" method of ""NewAndOverride""class!");
        }
    }

class Tester
    {
        /// <summary>
        /// 运行结果:
        /// The "RealMethod" method of "BeiseClass" class!
        /// The "RealMethod" method of "NewAndOverride" class!
        /// The "ViutualMethod" method of "BeiseClass"class!
        /// The "ViutualMethod" method of "NewAndOverride"class!
        ///
        /// The "RealMethod" method of "BeiseClass" class!
        /// The "ViutualMethod" method of "NewAndOverride"class!
        /// </summary>
        static void Main()
        {
            BeiseClass beiseClass = new BeiseClass();
            NewAndOverride newAndOverride = new NewAndOverride();
       
            beiseClass.RealMethod();
            newAndOverride.RealMethod();

beiseClass.ViutualMethod();
            newAndOverride.ViutualMethod();

Console.WriteLine();

//
            // 注意:可以看到隐藏(new)方法仍然存在,而被覆盖(override)的方法已经不存在了;
            //
            beiseClass = newAndOverride;
           
            beiseClass.RealMethod();
            beiseClass.ViutualMethod();

}
    }
}

【new】
使用 new 修饰符显式隐藏从基类继承的成员。若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并用 new 修饰符修饰它。

类 成员声明中可以使用与一个被继承的成员相同的名称或签名来声明一个成员。发生这种情况时,就称该派生类成员隐藏了基类成员。隐藏一个继承的成员不算是错 误,但这确实会导致编译器发出警告。若要取消此警告,派生类成员的声明中可以包含一个 new 修饰符,表示派生成员是有意隐藏基成员的。

using System;

namespace TheNewKeyword
{

class NewTestClassBase
    {
        public void PrintNewKeyword()
        {
            Console.WriteLine(@"This is base class!");
        }
    }

class NewTestClass : NewTestClassBase
    {
        <summary>
        /// 如果这样写:
        /// override public void PrintNewKeyword()
        ///
        /// 将产生编译错误:
        /// “TheNewKeyword.NewTestClass.PrintNewKeyword()” :
        /// 无法重写继承成员“TheNewKeyword.NewTestClassBase.PrintNewKeyword()”,
        /// 因为它未标记为 virtual、abstract 或 override。
        /// </summary>
        new public void PrintNewKeyword()
        {
            Console.WriteLine(@"This is ""new"" keyword!");
        }
    }

<summary>
    /// TheNewKeyword 测试“new”关键字。
    /// </summary>
    class TheNewKeyword
    {
        <summary>
        /// 运行结果:
        /// This is base class!
        /// This is "new" keyword!
        /// </summary
        static void Main()
        {
            //
            // TODO: 在此处添加代码以启动应用程序
            //
            NewTestClassBase newTestClassBase = new NewTestClassBase();
            NewTestClass newTestClass = new NewTestClass();

newTestClassBase.PrintNewKeyword();
            newTestClass.PrintNewKeyword();
        }
    }
}

转载于:https://www.cnblogs.com/baiyu/archive/2011/08/24/2152257.html

转:C#中的abstract与virtual相关推荐

  1. (转)C#中的Abstract和Virtual函数区分,因我老弄不明白这个问题,所以转到这儿

    发现很多朋友对于C#中的Abstract和Virtual函数区分得不是很清楚,下面我通过两段代码让大家看看这两者之间到底有什么区别~~ 开发环境: VS.net 2005 使用方法: 用以下代码覆盖p ...

  2. 转载-区分C#中的Abstract函数和Virtual函数

    发现很多朋友对于C#中的Abstract和Virtual函数区分得不是很清楚,下面我通过两段代码让大家看看这两者之间到底有什么区别~~ 开发环境: VS.net 2005 使用方法: 用以下代码覆盖p ...

  3. c#中的interface abstract与virtual的介绍与使用

    abstract 与virtual : 方法重写时都使用 override 关键字,interface中的方法和abstract方法都要求实现. 1:interface用来声明接口 1.1.只提供一些 ...

  4. c#中的interface abstract与virtual

    abstract 与virtual : 方法重写时都使用 override 关键字,interface中的方法和abstract方法都要求实现 interface用来声明接口 1.只提供一些方法规约, ...

  5. c#中的interface abstract 与 virtual(转)

    interface用来声明接口 1.只提供一些方法规约,不提供方法主体.  如: public interface IPerson {     void getName();//不包含方法主体 } 2 ...

  6. c#中abstract与virtual的区别

    1.abstract方法只能在抽象类中声明,虚方法则不是.    abstract方法必须在派生类中重写,而virtual则不必 2.abstract方法不能声明方法实体,       abstrac ...

  7. C#中Abstract和Virtual的区别

    转自原文 C#中Abstract和Virtual的区别 c# 中 Abstract和Virtual比较容易混淆,都与继承有关,并且涉及override的使用.下面讨论一下二者的区别: 一.Virtua ...

  8. C#中的static,interface,virtual,abstract,override的用法

    C# 是面向对象的程序设计语言,每一个函数都属于一个类. Static:当一个方法被声明为Static时,这个方法是一个静态方法,编译器会在编译时保留这个方法的实现. 也就是说,这个方法属于类,但是不 ...

  9. C#中Abstract和Virtual使用详解

    转载自: https://www.cnblogs.com/vaevvaev/p/6911788.html 在C#的学习中,容易混淆virtual方法和abstract方法的使用,现在来讨论一下二者的区 ...

最新文章

  1. 网络营销外包专员浅析尽管快照不见了网络营销外包仍在继续
  2. 二层以太网技术—Vecloud
  3. Python 计算程序运行时间
  4. vscode修改python终端_panda3d是python的一个高级的3D 渲染和游戏开发框架
  5. 【工业4.0】什么是工业4.0,这篇文章讲得明明白白!
  6. 用了这么久 IDEA,你真熟悉它的自动补全功能吗?
  7. xp系统打开计算机硬盘分区,XP系统下怎么进行硬盘分区啊?
  8. C# 特性(Attribute)之Flag特性
  9. 【互联网安全】阿里云安全专家为你详细解读内容安全及防护
  10. webpack的详细使用
  11. 可视化指标计算公式_基于OTU的alpha多样性指数计算和可视化
  12. 从零到卓越:京东客服即时通讯系统的技术架构演进历程(转)
  13. DirectX11,DirectX12,OpenGL,Vulkan学习资料
  14. python—简单的数据抓取一(简单的文字数据抓取(认识cookie)、简单的图片抓取)
  15. 12C GDS安装简记
  16. BGP路由器协议排错教程:BGP 路由通告的排错
  17. OD破解软件找断点方法系列【2】----万能断点法(XP系统)
  18. 未来新一代计算机发展趋势有,未来计算机的发展趋势
  19. 反映个把月才退了个零头 ——消费者投诉旅游平台退款难
  20. rx580显卡运行不了Linux,RX580吃鸡不流畅原因找到了 真相令人无语

热门文章

  1. 软件访问转向本地_我是如何从完整的初学者转向软件开发人员的,以及如何做到的...
  2. javascript_治愈JavaScript疲劳的研究计划
  3. 邮Z速递物流,让用户密码在网络中遨游
  4. 想转行学软件测试要注意哪些问题
  5. Oracle中的iot_type,oracle IOT表学习
  6. oracle mysql事物隔离级别_Oracle数据库事物隔离级别
  7. leetcode--罗马数字转整数--python
  8. Luogu P1082 同余方程(NOIP 2012) 题解报告
  9. Django使用数据库(Mariadb/Mysql)
  10. Hulu直播服务难点解析(一):系统需求