C#中Abstract 、Virtual和Override的使用

1. abstract 修饰符指sql教程示所修饰的内容缺少实java基础教程现或未完全实现。 abstract 修饰符可用于类、方法、属性、索引器和事件。在类声明中使用abstract修饰符python基础教程以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。

(1)抽象类具有以下特性:

1) 抽象类不能实例化。

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

3) 不能用 sealed 修饰符修饰抽象类,因为这两个修饰符的含义是相反的。采用 sealed 修饰符的类无法继承,而 abstract 修饰符要求对类进行继承。

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

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

(2)抽象方法具有以下特性:

1) 抽象方法是隐式c#教程的虚方法。

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

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

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

public abstract class parent

{

protected int x=100;

protected int y = 200;

public abstract void function();

public abstract int X { get; }

public abstract int Y { get; }

}

public class newperson : parent

{

public override void function()

{

x++;

y++;

}

public override int X

{

get { return x+100; }

}

public override int Y

{

get { return y+100; }

}

}

static void Main(string[] args)

{

newperson p = new newperson();

Console.WriteLine(p.X);

Console.WriteLine(p.Y);

p.function();

Console.WriteLine(p.X);

Console.WriteLine(p.Y);

Console.ReadKey();

}

2. virtual关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。虚拟成员的实现可由派生类中的重写成员更改。调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。默认情况下,方法是非虚拟的。不能重写非虚方法。virtual 修饰符不能与 static、abstract, private 或 override 修饰符一起使用。和抽象方法的相同点是都用了override关键字进行重写方法,不同点是抽象方法必须存在于抽象类中,而子类必须重写,除非子类也是抽象的。

public class Dimensions

{

public const double PI = Math.PI;

protected double x;

protected double 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()

{

Console.WriteLine(base.Area());

return PI * x * x;

}

}

public class Sphere : Dimensions

{

public Sphere(double r) : base(r,0) { }

public override double Area()

{

return 4 * PI * x * x;

}

}

public 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(string[] args)

{

Dimensions P = new Circle(5.0);

Sphere sphere = new Sphere(10);

Cylinder cylinder = new Cylinder(10, 10);

Console.WriteLine(P.Area());

Console.WriteLine(sphere.Area());

Console.WriteLine(cylinder.Area());

Console.ReadKey();

}

3.override 方法提供从基类继承的成员的新实现。由 override 声明重写的方法称为重写基方法。重写的基方法必须与 override 方法具有相同的签名。不能重写非虚方法或静态方法。重写的基方法必须是 virtual、abstract 或 override 的。 override 声明不能更改 virtual 方法的可访问性。 override 方法和 virtual 方法必须具有相同的访问级别修饰符。重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须是 virtual、abstract 或 override 的。

4. base和this的区别

1)base作用:用于从派生类中访问基类的成员,调用基类上已被其他方法重写的方法。指定创建派生类实例时应调用的基类构造函数。

注:从静态方法中使用 base 关键字是错误的。
2)区别:

base 是子类中引用父类,用于在派生类中访问重写的基类成员。
this 是当前类,引用自己,用于访问本类的成员,当然也包括继承而来公有和保护成员。

3)注意:
a).在静态成员中使用base和this都是不允许的。原因是,base和this访问的都是类的实例,也就是对象,而静态成员只能由类来访问,不能由对象来访问。
b).base是为了实现多态而设计的。
c).使用this或base关键字只能指定一个构造函数,也就是说不可同时将this和base作用在一个构造函数上。
d).除了base,访问基类成员的另外一种方式是:显示的类型转换来实现。只是该方法不能为静态方法。

### C# 中 `abstract` `virtual` 关键字的区别及使用场景 #### 定义与特性 - **Virtual 方法**:可以在任意类中定义,具有具体的实现。派生类可以选择重写该方法,也可以继续使用基类的实现[^1]。 - **Abstract 方法**:必须定义在抽象类中,本身没有任何具体实现,强制要求派生类提供自己的实现[^2]。 #### 实现细节对比 | 特性 | Virtual 方法 | Abstract 方法 | |--------------------|-----------------------------------------------|-----------------------------------------| | 是否需要实现 | 提供默认实现 | 不允许提供实现 | | 存放位置 | 普通类或抽象类 | 必须位于抽象类 | | 强制子类覆盖 | 非强制 | 强制 | #### 示例代码比较 以下展示了两种关键字的实际应用差异: ```csharp using System; public class BaseClass { // Virtual method with default implementation public virtual void Display() { Console.WriteLine("Base Class Method"); } // Abstract method must be implemented by derived classes public abstract void Process(); } public class DerivedClass : BaseClass { // Override the virtual method public override void Display() { Console.WriteLine("Derived Class Overridden Method"); } // Implement the abstract method public override void Process() { Console.WriteLine("Processing in Derived Class..."); } } class Program { static void Main(string[] args) { BaseClass obj = new DerivedClass(); obj.Display(); // Calls overridden version from DerivedClass. obj.Process(); // Calls required implementation of abstract method. Console.ReadLine(); } } ``` #### 使用场景分析 - 当设计一个通用功能时,如果某些行为可能不需要改变或者已经有合理默认逻辑,则应采用虚拟函数(`virtual`);这样既提供了灵活性又保留了一定程度上的标准化处理流程[^1]。 - 若某个操作完全依赖于特定类型的内部状态而无法给出有意义的基础版本,并且期望所有继承者都重新定义此动作的话,则应该运用抽象成员(`abstract`)[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值