毛毛的小窝 — 关注技术交流、让我们一起成长

导航

abstract, virtual, override, new 关键字的用法

简单一点来说,相见msdn的介绍。

virtual:包含函数体,继承类无需重写,当然也可以重写;
abstract:不包含函数体,继承类必须重写;
new:一般方法,继承类想覆盖之,采用new关键字进行;

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Keywords
{
    
public abstract class ShapeClass
    
{
        
public string GetShapeName()
        
{
            
return "shape class";
        }


        
public abstract int Area();

        
public virtual int Volume()
        
{
            
return 11;
        }


    }


    
public class Square : ShapeClass
    
{
        
// 采用new关键字重写基类一般方法
        public new string GetShapeName()
        
{
            
return "square";
        }


        
// 必须重写
        public override int Area()
        
{
            
return 22;
        }


        
// 可以重写,也可以不重写
        public override int Volume()
        
{
            
//return base.Volume();
            return 33;
        }

    }


    
public class Program
    
{
        
public static void Main(string[] args)
        
{
            Square square 
= new Square();
            Console.WriteLine(square.GetShapeName());
            Console.WriteLine(square.Area());
            Console.WriteLine(square.Volume());

            Console.ReadLine();
        }

    }

}

 

附录:msdn的介绍

 

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

在此例中,类 Square 必须提供 Area 的实现,因为它派生自 ShapesClass

  复制代码
        abstract class ShapesClass
            {
            abstract public int Area();
            }
            class Square : ShapesClass
            {
            int x, y;
            // Not providing an Area method results
            // in a compile-time error.
            public override int Area()
            {
            return x * y;
            }
            }

有关抽象类的更多信息,请参见抽象类、密封类及类成员(C# 编程指南)

备注

抽象类具有以下特性:

  • 抽象类不能实例化。

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

  • 不能用 sealed(C# 参考)修饰符修改抽象类,这意味着抽象类不能被继承。

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

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

抽象方法具有以下特性:

  • 抽象方法是隐式的虚方法。

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

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

      复制代码
    public abstract void MyMethod();
  • 实现由一个重写方法提供,此重写方法是非抽象类的成员。

  • 在抽象方法声明中使用 staticvirtual 修饰符是错误的。

除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。

  • 在静态属性上使用 abstract 修饰符是错误的。

  • 在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属性。

抽象类必须为所有接口成员提供实现。

实现接口的抽象类可以将接口方法映射到抽象方法上。例如:

  复制代码
interface I
            {
            void M();
            }
            abstract class C: I
            {
            public abstract void M();
            }

示例

在本例中,DerivedClass 类是从抽象类 BaseClass 派生的。抽象类包含一个抽象方法 AbstractMethod 和两个抽象属性 XY

  复制代码
// abstract_keyword.cs
            // Abstract Classes
            using System;
            abstract class BaseClass   // Abstract class
            {
            protected int _x = 100;
            protected int _y = 150;
            public abstract void AbstractMethod();   // Abstract method
            public abstract int X    { get; }
            public abstract int Y    { get; }
            }
            class DerivedClass : BaseClass
            {
            public override void AbstractMethod()
            {
            _x++;
            _y++;
            }
            public override int X   // overriding property
            {
            get
            {
            return _x + 10;
            }
            }
            public override int Y   // overriding property
            {
            get
            {
            return _y + 10;
            }
            }
            static void Main()
            {
            DerivedClass o = new DerivedClass();
            o.AbstractMethod();
            Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
            }
            }

输出

 
x = 111, y = 161

注释

在上面的示例中,如果试图通过使用下面的语句将抽象类实例化:

  复制代码
BaseClass bc = new BaseClass();   // Error

将出现错误,指出编译器无法创建抽象类“BaseClass”的实例。

 

virtual 关键字用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。例如,此方法可被任何继承它的类重写。

  复制代码
public virtual double Area()
            {
            return x * y;
            }

虚拟成员的实现可由派生类中的重写成员更改。有关使用 virtual 关键字的更多信息,请参见使用 Override 和 New 关键字控制版本(C# 编程指南)了解何时使用 Override 和 New 关键字(C# 编程指南)

备注

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

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

virtual 修饰符不能与 static、abstract 和 override 修饰符一起使用。

除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。

  • 在静态属性上使用 virtual 修饰符是错误的。

  • 通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。

示例

在该示例中,Dimensions 类包含 xy 两个坐标和 Area() 虚方法。不同的形状类,如 CircleCylinderSphere 继承 Dimensions 类,并为每个图形计算表面积。每个派生类都有各自的 Area() 重写实现。根据与此方法关联的对象,通过调用正确的 Area() 实现,该程序为每个图形计算并显示正确的面积。

在前面的示例中,注意继承的类 CircleSphereCylinder 都使用了初始化基类的构造函数,例如:

  复制代码
public Cylinder(double r, double h): base(r, h) {}

这类似于 C++ 的初始化列表。

  复制代码
// cs_virtual_keyword.cs
            using System;
            class TestClass
            {
            public class Dimensions
            {
            public const double PI = Math.PI;
            protected double x, y;
            public Dimensions()
            {
            }
            public Dimensions(double x, double y)
            {
            this.x = x;
            this.y = y;
            }
            public virtual double Area()
            {
            return x * y;
            }
            }
            public class Circle : Dimensions
            {
            public Circle(double r) : base(r, 0)
            {
            }
            public override double Area()
            {
            return PI * x * x;
            }
            }
            class Sphere : Dimensions
            {
            public Sphere(double r) : base(r, 0)
            {
            }
            public override double Area()
            {
            return 4 * PI * x * x;
            }
            }
            class Cylinder : Dimensions
            {
            public Cylinder(double r, double h) : base(r, h)
            {
            }
            public override double Area()
            {
            return 2 * PI * x * x + 2 * PI * x * y;
            }
            }
            static void Main()
            {
            double r = 3.0, h = 5.0;
            Dimensions c = new Circle(r);
            Dimensions s = new Sphere(r);
            Dimensions l = new Cylinder(r, h);
            // Display results:
            Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
            Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
            Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
            }
            }

输出

 
Area of Circle   = 28.27
            Area of Sphere   = 113.10
            Area of Cylinder = 150.80

 

posted on 2008-11-28 10:06  mjgforever  阅读(689)  评论(0编辑  收藏  举报