C#中的方法重写类似于
C ++中的虚函数
。方法重写是一种允许从派生类中的另一个类(基类)调用函数的技术。在派生类中创建与基类中的方法具有相同签名的方法称为方法重写。
简而言之, Overrideing是一项功能, 它允许子类或子类提供其超类或父类之一已经提供的方法的特定实现。当子类中的方法与其父类中的方法具有相同的名称, 相同的参数或签名以及相同的返回类型(或子类型)时, 则称子类中的方法覆盖父类中的方法。类。方法重写是C#实现的一种方法
.
被覆盖声明所覆盖的方法称为覆盖基础方法。覆盖方法是从基类继承的成员的新实现。覆盖的基本方法必须是虚拟的, 抽象的或覆盖的。
例子:
class base_class
{
public void gfg();
}
class derived_class : base_class
{
public void gfg();
}
class Main_Method
{
static void Main()
{
derived_class d = new derived_class();
d.gfg();
}
}
在这里, 基类在派生类和方法中继承gfg()在两个类中具有相同签名的标记将被覆盖。
在C#中, 我们可以使用3种类型的关键字进行方法覆盖:
虚拟关键字:
此修饰符或关键字在基类方法中使用。它用于修改
基类
对于
覆写
派生类中的特定方法。
覆盖:
此修饰符或关键字与派生类方法一起使用。用于修改
虚拟
or
抽象
方法成
派生类
在基类中呈现。
class base_class
{
public virtual void gfg();
}
class derived_class : base_class
{
public override void gfg();
}
class Main_Method
{
static void Main()
{
derived d_class = new derived_class();
d.gfg();
base_class b = new derived_class();
b.gfg();
}
}
首先, d引用类的对象派生类它调用gfg()班上的派生类然后, b引用类库的引用, 它保存派生类的对象, 并调用gfg()类的派生。这里gfg()方法获得基类的许可才能覆盖派生类中的方法。
范例1:不使用虚拟和替代修饰符的方法替代
// C# program to demonstrate the method overriding
// without using 'virtual' and 'override' modifiers
using System;
// base class name 'baseClass'
class baseClass
{
public void show()
{
Console.WriteLine( "Base class" );
}
}
// derived class name 'derived'
// 'baseClass' inherit here
class derived : baseClass
{
// overriding
new public void show()
{
Console.WriteLine( "Derived class" );
}
}
class GFG {
// Main Method
public static void Main()
{
// 'obj' is the object of
// class 'baseClass'
baseClass obj = new baseClass();
// invokes the method 'show()'
// of class 'baseClass'
obj.show();
obj = new derived();
// it also invokes the method
// 'show()' of class 'baseClass'
obj.show();
}
}
输出如下:
Base class
Base class
说明:在此程序中, 对象对象调用类baseClass两次并调用方法节目()上课baseClass。为避免此问题, 我们使用virtual和override关键字。
范例2:使用方法覆盖虚拟和覆写修饰符。
// C# program to illustrate the use of
//'virtual' and 'override' modifiers
using System;
class baseClass {
// show() is 'virtual' here
public virtual void show()
{
Console.WriteLine( "Base class" );
}
}
// class 'baseClass' inherit
// class 'derived'
class derived : baseClass
{
//'show()' is 'override' here
public override void show()
{
Console.WriteLine( "Derived class" );
}
}
class GFG {
// Main Method
public static void Main()
{
baseClass obj;
// 'obj' is the object
// of class 'baseClass'
obj = new baseClass();
// it invokes 'show()'
// of class 'baseClass'
obj.show();
// the same object 'obj' is now
// the object of class 'derived'
obj = new derived();
// it invokes 'show()' of class 'derived'
// 'show()' of class 'derived' is overridden
// for 'override' modifier
obj.show();
}
}
输出如下:
Base class
Derived class
基本关键字:
这用于从派生类访问基类的成员。它基本上用于访问基类的构造函数和方法或函数。 base关键字不能在静态方法中使用。 Base关键字指定在创建派生类的实例时应调用基类的构造函数。
使用Base关键字:
- 从派生类调用基类的方法或函数。
- 在调用基类内部的构造函数时遗产.
范例1:
// C# program to show the use of 'base'
// keyword in method overriding
using System;
// base class
public class web {
string name = "lsbin" ;
// 'showdata()' is member method, // declare as virtual
public virtual void showdata()
{
Console.WriteLine( "Website Name: " + name);
}
}
// derived class
// class 'web' is inherits
// class 'stream'
class stream : web {
string s = "Computer Science" ;
//'showdata()' is overridden
// in derived class
public override void showdata()
{
// Calling 'showdata()' of base
// class using 'base' keyword
base .showdata();
Console.WriteLine( "About: " + s);
}
}
class GFG {
// Main Method
static void Main()
{
// 'E' is object of class stream
// also works as object of
// class 'web'
stream E = new stream();
// it first invokes 'showdata()'
// of class 'web' then it invokes
// 'showdata()' of class 'stream'
E.showdata();
}
}
输出如下:
Website Name: lsbin
About: Computer Science
范例2:基本关键字如何指定调用基类构造函数创建派生类实例时从派生类中获取。
// C# program to show how base keyword
// specifies the calling of base-class
// constructor from the derived class
// when derived class instances are created
using System;
// base class
public class clssA {
int n1, n2;
// default constructor
public clssA()
{
Console.WriteLine( "Default Constructor Invoked" );
}
// parameterized constructor
public clssA( int i, int j)
{
// consturct values
n1 = i;
n2 = j;
Console.WriteLine( "Parameterized Constructor Invoked" );
Console.WriteLine( "Invoked Values are: " + n1 + " and " + n2);
}
}
// derived class
public class DerivedClass : clssA
{
// This constructor will instantiate
// 'clssA()' [no argument constructor]
// using 'base' keyword
public DerivedClass() : base () { }
// This constructor will instantiate
// 'clssA(int i, int j)' [parameterized
// constructor] using 'base' keyword
public DerivedClass( int i, int j) : base (i, j) { }
// Main Method
static void Main()
{
// invoke no argumanet constructor
DerivedClass d1 = new DerivedClass();
Console.WriteLine();
// invoke parameterized constructor
DerivedClass d2 = new DerivedClass(10, 20);
}
}
输出如下:
Default Constructor Invoked
Parameterized Constructor Invoked
Invoked Values are: 10 and 20
范例3:它显示了base关键字如何指定基类建设者从派生类调用, 也使用派生类的base关键字调用方法。
// C# program to show how 'base' keyword specifies
// the base-class constructor that called from
// derived class and also calling a method 'swap'
// from derived class using base keyword
using System;
// base class
public class clssA {
public int n1, n2;
// default constructor
public clssA()
{
Console.WriteLine( "In clssA 'no argument constructor' invoked" );
}
// parameterized constructor
public clssA( int i, int j)
{
// consturct values
n1 = i;
n2 = j;
Console.WriteLine( "in clssA 'parameterized constructor' invoked" );
Console.WriteLine( "the invoked values are " + n1 + " and " + n2);
Console.WriteLine();
}
public virtual void swap()
{
Console.WriteLine( "swap function of base class(clssA) invoked" );
Console.WriteLine( "Before swap num1 = {0} and num2 = {1}" , n1, n2);
// swapping
int t = n1;
n1 = n2;
n2 = t;
Console.WriteLine( "After swap num1 = {0} and num2 = {1}" , n1, n2);
}
}
// derived class
public class DerivedClass : clssA {
// This constructor will instantiate
// 'clssA' [no argument constructor]
// using 'base' keyword
public DerivedClass() : base () { }
// This constructor will instantiate
// 'clssA' [parameterized constructor]
// using 'base' keyword
public DerivedClass( int i, int j) : base (i, j) { }
public override void swap()
{
// it access the swap function of
// 'clssA' using 'base' keyword
base .swap();
Console.WriteLine();
Console.WriteLine( "Swap function of derived class invoked" );
Console.WriteLine( "Before swap num1 = {0} and num2 = {1}" , n1, n2);
// swapping
int t = n1;
n1 = n2;
n2 = t;
Console.WriteLine( "After swap num1 = {0} and num2 = {1}" , n1, n2);
}
// Main Method
static void Main()
{
// invoke no argumanet constructor
DerivedClass d1 = new DerivedClass();
Console.WriteLine();
// invoke parameterized constructor
DerivedClass d2 = new DerivedClass(10, 20);
// calling swap function
d2.swap();
}
}
输出如下:
In clssA 'no argument constructor' invoked
in clssA 'parameterized constructor' invoked
the invoked values are 10 and 20
swap function of base class(clssA) invoked
Before swap num1 = 10 and num2 = 20
After swap num1 = 20 and num2 = 10
Swap function of derived class invoked
Before swap num1 = 20 and num2 = 10
After swap num1 = 10 and num2 = 20
注意:
- 仅在派生类中才可以覆盖方法。因为在基类的派生类中重写了方法。
- 方法必须是用于重写的非虚拟或静态方法。
- 覆盖方法和虚拟方法都必须具有相同的访问级别修饰符。