• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
激情 希望 斗志昂扬
Records of growth process 专注微软技术
博客园    首页    新随笔    联系   管理    订阅  订阅

new、abstract、virtual、override,sealed关键字区别和使用代码示例

本文是整理牛人精华贴所得,非100%原创

 

new 与 override的区别

 引用AnyTao博客中的一句话:
覆写(override)与重载(overload),是成就.NET面向对象多态特性的基本技术之一
正如某网友说的那一句话:
Override 覆写 就是把原来的换掉了
new        新的 就是两个共存着

使用override重写xx方法,通过父类引用一样只能看到重写后的方法;
如果使用new隐藏xx方法,父类子类引用各自对应方法;

override重写虚方法,那么就只剩下重写以后的方法;
new隐藏基类的方法,那么基类的方法和当前类的方法同时存在只是被隐藏了;

 

 

使用override修饰符主要用来修改方法、属性、索引器或事件。重写基方法必须与重写方法具有相同的名称。
        不能重写非虚方法或静态方法。重写基方法必须是虚拟的、抽象的或重写的。
       重写声明不能更改虚方法的可访问性。重写方法和虚方法必须具有相同的访问级修饰符。例如:虚方法为public的,重新方法也必须是public的。
        不能使用下列修饰符修改重写方法:
        new        static        virtual        abstract

        重写属性声明必须指写与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或是重写的。

要求:(三相同)
1、方法名称相同
2、参数列表相同
3、返回值类型相同
一句话,只需要重新写方法内部的内容!

,override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已


 

先看abstract和override使用方法

abstract class Base

    {

        public virtual void work()

        {

            MessageBox.Show("基类--开始工作");

        }

        public virtual void outwork()

        {

            MessageBox.Show("基类--下班");

        }

        

        Public abstract void Pay();       //声明抽象方法,必须要被子类new 或 override;只有当类是abstract时才可以声明abstract方法    

    }

    class Employee : Base

    {

        public new void work()

        {

            MessageBox.Show("子类(new)--开始工作");

        }

        public override void outwork()   //覆写抽象方法(一定要在子类覆写父类的抽象方法)

        {

            MessageBox.Show("子类(override)下班");

        }

}               

//测试代码

        

Code
          //第一种情况
            Employee emp = new Employee();

            emp.work();              
//子类(new)--开始工作

            emp.outwork();          
//子类(override)下班     

            
//第二种情况
            Employee emp = new Employee();

            Base b 
= (Base)emp;   //指向抽象类了

            b.work();                
//基类--开始工作

            b.outwork();             
//子类(override)下班   被子类覆写了,所以不是显示基类下班

            
//第三种情况
            Base b = new Employee();

            
//同上面是一样的

            b.work();                
//基类--开始工作

            b.outwork();             
//子类(override)下班

            Console.ReadLine();

   

new声明的方法,当使用子类的类型来调用的时候,它会运行子类中的函数,而如果类型是基类的话,被隐藏的基类函数就会站到前台来。只有使用virtual定义基类中的函数,并使用override标记子类中的函数,才可以达到想要的多态类(始终调用子类的方法)。

在子类中new父类中的方法,父类中的方法不一定是虚类型,即virtual

但是在子类中override父类中的方法,父类的方法一定得是虚类型,

 

代码示例:

    abstract class Animal

    {

        public abstract void Drink();

        public abstract void GotoBed();

    }

    class Dog : Animal

    {

        public override void Drink()

        {

            MessageBox.Show("小狗喝水");

        }

        public override void GotoBed()

        {

            MessageBox.Show("小狗睡觉");

        }

        public override string ToString()   //也可:public new string ToString()

        {

            return "小狗";

        }

    }

总结:

1、                抽象方法,必须要被子override;只有当类是abstract时才可以声明abstract方法  

2、                因为abstract方法没有方法实现,其子类只能对其abstract方法进行override,不能new(如果可以new的话,那么类的类型是父类的话,类的方法执行的是父类的方法而非子类的方法,而父类的方法却没有方法实现,那么将如何执行呢?)

3、     Selaed 方法必须与override连用,也就是说实现sealed方法的类的父类必须实现了此方法(sealed关键字有两个作用:1,密封类不能被继承。2:密封方法重写基类中的方法,但其本身不能在任何派生类中进一步重写,Selaed 方法必须与override连用)

    如下,A声明了virtual方法A1,那么A的子类AA才能对Pay进行密封重写,AA的子类不能对A1重写或覆盖。

sealed方法的使用代码示例:

    class A

    {

        public virtual void A1()

        {

            MessageBox.Show("A---A1");   

        }

    }

    class AA:A

    {

        public sealed override void A1()

        {

            MessageBox.Show("AA---A1");

        }        

    }

总结:

Public abstract void pay();                 abstract方法没有方法实现,必须继承

Public sealed override void pay(){}      sealed方法必须是重写父类的方法

Public static void pay(){}                   static方法通过类名访问

Public virtual void pay(){}                  virtual方法子类可以对其override或new

Public new void pay(){}                     父类的方法pay不一定是virtual

Public override void pay(){}                父类的方法pay一定要是virtual

 

new、abstract、virtual、override关键字的使用代码示例

 

public abstract class People   //abstract 说明类People是一个抽象类,不能被实例的
    {
        
public People()
        {
        }

        
public void Work()
        {
            MessageBox.Show(
"开始工作!");
        }

        
public virtual void GetOffWork()   //虚函数,说明此方法可以被子类覆盖(override)
        {
            MessageBox.Show(
"下班啦!");
        } 
    } 

    
public class Manage:People   //继承Popele类
    {
        
public Manage()
        {
        } 

        
new public void Work()   //因为基类已经实现了Work方法,而在子类中又实现了Work方法,                                         //所以编译器会报警,在前面加上 new(隐藏基类方法),是将警报关闭。
        {
            
base.Work();   //调用基类Popele的方法。显示“开始工作”
            
//MessageBox.Show("管理员开始工作罗!");
        } 

        
public override void GetOffWork()      //覆盖基类的方法
        {
            MessageBox.Show(
"管理员下班啦");
        } 
    }

    
public class Employee():People
    {
       
public Employee()
       {}

        
new public void GetOffWork()      //virtual方法仍然可以 new,abstract方法不能用new
        {
            MessageBox.Show(
"职员下班啦!");
        } 

    }

以上应该应该几点:
1、如果父类方法没有加virtual关键字,即不是一个虚方法,则在子类中只能隐藏基类方法,而不能覆盖。
2、如果父类方法加了virtual关键字,即它是一个虚方法,在子类中一样可以隐藏。
3、如果子类实现了父类相同的方法(相同的方法名称及签名),而没有new,在编译时会报警,但编译仍然能够通过!
3、调用父类方法:base.方法名()
4、abstract类是一个抽象类,不能被实例化

 

posted @ 2009-04-08 12:02  贤  阅读(2074)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3