您的位置:首页 > 编程语言 > C#

C#中的抽象类、抽象方法和虚方法

2010-11-17 11:58 274 查看
虚方法和抽象方法都可以供派生类重写,它们之间有什么区别呢?
1. 虚方法必须有实现部分,并为派生类提供了覆盖该方法的选项;

抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。如:
//抽象方法
public abstract class Animal
{
 public abstract void Sleep();
 public abstract void Eat();
}
//虚方法
public class Animal
{
 public virtual void Sleep(){}
 public virtual void Eat(){}
}

2. 抽象方法只能在抽象类中声明, 抽象方法必须在派生类中重写;

虚方法不是 也不必要重写。其实如果类包含抽象方法,那么该类也是抽象的,也必须声明为抽象的。如:
public class Animal
{
 public abstract void Sleep();
 public abstract void Eat();
}
编译器会报错:
Main.cs(10): 'VSTest.Animal.Sleep()' is abstract but it is contained in nonabstract class 'VSTest.Animal'
Main.cs(11): 'VSTest.Animal.Eat()' is abstract but it is contained in nonabstract class 'VSTest.Animal'

3. 抽象方法必须在派生类中重写,这一点跟接口类似,虚方法不必。

抽象方法不能声明方法实体 而虚方法可以 包含抽象方法的类不能实例化 ,而包含虚方法的类可以实例化!如:
public abstract class Animal
{
 public abstract void Sleep();
 public abstract void Eat();
}

public class Cat : Animal
{
 public override void Sleep()
 {
 Console.WriteLine( "Cat is sleeping " );
 }
 // we need implement Animal.Eat() here
}

编译器会报错:Main.cs(14): 'VSTest.Cat' does not implement inherited abstract member 'VSTest.Animal.Eat()',因为我们没有实现抽象类中所有抽象方法。

【抽象类】

abstract 修饰符可与类和方法一起使用
定义抽象类的目的是提供可由其子类共享的一般形式。
子类可以根据自身需要扩展抽象类。
抽象类不能实例化。
抽象方法没有函数体。
抽象方法必须在子类中给出具体实现。
在以下情况下,某个类将成为抽象类:

★ 当一个类的一个或多个方法为抽象方法时。
★ 当该类为一个抽象类的子类,并且没有为所有抽象方法提供实现细节或方法主体时。
★ 当一个类实现一个接口,并且没有为所有抽象方法提供实现细节或方法主体时。

abstract class Employee {
public int basic = 2000;
public abstract void salary();//抽象方法
}
class Manager : Employee{
public override void salary() {
Console.WriteLine("薪资等于 "+basic*5);
}
}
class Worker : Employee {
public override void salary() {
Console.WriteLine("薪资等于 "+basic*2);
}
}

【抽象类和抽象方法】

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

【引用】

abstract class ClassOne{
//类实现-定义抽象方法、定义抽象访问器等
}

【抽象类的特性】

抽象类不能实例化。
抽象类可以包含抽象方法和抽象访问器。
不能用 sealed修饰符修改抽象类。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
在方法或属性声明中使用 abstract 修饰符以指示方法或属性不包含实现。抽象方法具有的特性:
抽象方法是隐式的虚方法;只允许在抽象类中使用抽象方法声明。
抽象方法声明不提供实际的实现,没有方法体;方法声明以一个分号结束,并且在签名后没有大括号 ({ })。
方法实现有一个非抽象类中重写方法实现。
在抽象方法声明不能使用static或virtual 修饰符。
在派生类中,通过包括使用override修饰符的属性声明,可以重写抽象的继承属性。

abstract class ShapesClass {
abstract public int Area();
}
class Square : ShapesClass {
int x, y;
public override int Area() {
return x * y;
}
}

抽象类中的方法不一定都是抽象方法;抽象类也可以容纳有具体实现的方法或者称为具体方法。但是含有抽象方法的类必然是抽象类。

【abstract关键字】
abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
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;
}
}

【抽象类具有以下特性】

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

【抽象方法具有以下特性】

抽象方法是隐式的虚方法。
只允许在抽象类中使用抽象方法声明。
因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。
public abstract void MyMethod();
实现由一个重写方法override提供,此重写方法是非抽象类的一个成员。
在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。
在静态属性上使用 abstract 修饰符是错误的。
在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属性。
抽象类必须为所有接口成员提供实现。

实现接口的抽象类可以将接口方法映射到抽象方法上。
interface I {
void M();
}
abstract class C: I {
public abstract void M();
}

【虚方法与抽象方法的区别】

虚方法
用virtual修饰
要有方法体,哪怕是一个分号
可以被子类override
除了密封类外读可以重写
抽象方法
用abstract修饰
不允许有方法体
必须被子类override
只能在抽象类中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息