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种类型的关键字进行方法覆盖:
- 虚拟关键字:此修饰符或关键字在基类方法中使用。它用于修改基类中的方法,以覆盖派生类中的特定方法。
- 覆盖:此修饰符或关键字与派生类方法一起使用。它用于将虚拟方法或抽象方法修改为派生类,该派生类呈现在基类中。
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指的是类derived_class的目的和它调用GFG()的类derived_class然后,B指的是类碱的引用,并将它保持派生类的对象,并将其调用的类的GFG()衍生的。在这里, gfg()方法获得基类的许可,以覆盖派生类中的方法。
示例1:不使用虚拟修饰符和覆盖修饰符的方法覆盖
C#
// 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();
}
}
C#
// 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();
}
}
C#
// C# program to show the use of 'base'
// keyword in method overriding
using System;
// base class
public class web {
string name = "GeeksForGeeks";
// '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();
}
}
C#
// 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);
}
}
C#
// 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();
}
}
Base class
Base class
说明:在此方案中,对象OBJ所调用类基类两次并调用类基类的方法展()。为避免此问题,我们使用virtual和override关键字。
示例2:使用virtual和override修饰符的方法重写。
C#
// 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关键字指定在创建派生类的实例时应调用基类的构造函数。
使用Base关键字:
- 从派生类中调用基类的方法或函数。
- 在继承时在基类内部调用构造函数。
范例1:
C#
// C# program to show the use of 'base'
// keyword in method overriding
using System;
// base class
public class web {
string name = "GeeksForGeeks";
// '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: GeeksForGeeks
About: Computer Science
示例2:创建派生类实例时,base关键字如何指定派生类对基类构造函数的调用。
C#
// 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#
// 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
笔记:
- 仅在派生类中才可以覆盖方法。因为在基类的派生类中重写了方法。
- 非虚拟或静态方法不能被覆盖。
- 覆盖方法和虚拟方法都必须具有相同的访问级别修饰符。