Posted by & filed under Uncategorized.

About chen xiang

Xiang Chen has written 52 post in this blog.

在C#中,有时有搞不明白的修饰符,abstract 与 virtual。

首先去MSDN看了看,http://msdn.microsoft.com/en-us/library/sf985hc5(VS.80).aspx。

这里面对abstract是这么定义的:

Abstract classes have the following features:

  • An abstract class cannot be instantiated.
  • An abstract class may contain abstract methods and accessors.
  • It is not possible to modify an abstract class with the sealed (C# Reference) modifier, which means that the class cannot be inherited.
  • A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.

Use the abstract modifier in a method or property declaration to indicate that the method or property does not contain implementation.

Abstract methods have the following features:

  • An abstract method is implicitly a virtual method.
  • Abstract method declarations are only permitted in abstract classes.
  • Because an abstract method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no curly braces ({ }) following the signature.
  •  The implementation is provided by an overriding method override (C# Reference), which is a member of a non-abstract class.
  • It is an error to use the static or virtual modifiers in an abstract method declaration.

Abstract properties behave like abstract methods, except for the differences in declaration and invocation syntax.

  • It is an error to use the abstract modifier on a static property.
  • An abstract inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.

大概的意思就是:

  • 抽象类是不能实例化的。
  • 抽象类可以包含抽象方法和属性。
  • 不能在抽象类上加sealed修饰符,因为那样抽象类就不能被继承。
  • 从抽象类继承的非抽象类,必须实现它所继承的所有抽象方法和属性。

在方法或属性中使用abstract修饰符,则说明此方法或者属性是没有具体代码实现的,仅仅只有定义。
比如:public abstract void AbstractMethod();   // Abstract method

  • 在静态属性上加abstract修饰符将会产生错误。
  • 继承类中的被继承的抽象属性可以通过加上override修饰符来重载实现属性的定义。

然后又看virtual的说明,http://msdn.microsoft.com/en-us/library/9fkccyh4(VS.80).aspx。

When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.

By default, methods are non-virtual. You cannot override a non-virtual method.

You cannot use the virtual modifier with the staticabstract, private or override modifiers.

Virtual properties behave like abstract methods, except for the differences in declaration and invocation syntax.

  • It is an error to use the virtual modifier on a static property.
  • A virtual inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.

其实简单说就是,抽象方法在抽象类中是没有具体实现的,只有定义,一旦继承了该类,就必须实现所有的抽象方法和属性,当然抽象类也可以有非抽象的方法。

而virtual方法在基类中是可以被实现的,也就是可以有具体的代码。在继承类中你可以加上override去重载的,可以实现不同的代码和功能,好比多态。

另外在抽象方法前面不可以再加virtual修饰符。一个virtual方法可以被abstract方法所重载。

当你决定是否要创建抽象类时,你肯定也会考虑使用interface。这两者在创建类的蓝图时(仅有方法或属性的定义而没有具体实现)是非常相似的,但也有不同的地方,下次研究interface的时候再具体说明吧。

下面举个小例子,这个例子也是参考MSDN的,可以比较好的说明abstract 与 virtual。

   // 基类
   public abstract class BaseClass
    {
        protected int _x = 100;
        protected int _y = 150;

        public abstract void AbstractMethod();   // Abstract method
        public abstract int X
        {
            get;
        }
        public abstract int Y
        {
            get;
        }

        public const double PI = Math.PI;

        public virtual double Area(double x, double y)
        {
            return x * y;
        }
    }

    // 继承类
    public 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;
            }
        }

        public override double Area(double x, double y)
        {
            return 2 * PI * x * x + 2 * PI * x * y;
        }
    }

    //  在ASP.Net中运用
    protected void Page_Load(object sender, EventArgs e)
    {
        DerivedClass o = new DerivedClass();
        o.AbstractMethod();
        Label1.Text = “x = ” + o.X + “<br /> y= ” + o.Y + “<br /> Area =” + o.Area(3, 5);
    }

结果是:

x = 111
y= 161
Area =150.79644737231

Leave a Reply

  • (will not be published)