1.虚方法:
使用virtual关键字定义,当子类继承父类时,可以对父类中的虚方法进行重写。
如下面代码中的类B,它继承类A,类A实现了接口I(实现了接口中的foo()方法)。在类A中使用virtual将foo()方法定义为虚方法,故在子类B中就可以重写foo()方法。这样就不会执行类A中的foo()方法,只执行类B中的foo()方法。类B中使用override关键字定义foo()方法,表示该方法复写了父类中的虚方法。
在子类中如果需要用到父类虚方法中的数据,可以在子类的覆盖方法中通过base.方法名()调用它【例如base.foo();】。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
public interface I
{
void foo();
}
class A : I
{
//虚方法:使用virtual关键字定义
public virtual void foo()
{
Console.WriteLine("*");
}
}
class B : A
{
//override关键字作用是对父类的virtual虚方法进行重写
public override void foo()
{
Console.WriteLine("#");
//如果父类的虚方法中有我们需要的数据,可以在子类的覆盖方法中调用它,base.foo()。
base.foo();
}
}
public class Test
{
static void Main(string[] args)
{
// your code goes here
B b = new B();
b.foo();
Console.ReadLine();
}
}
}
注意:
这个方法其实就是为了重写方法而存在的(在声明中包含virtual关键字),否则没感觉到它存在的意义。
其一:因为要重写所以它的访问类型如果为private则毫无意义阻碍了重写动作的进行也就是它不能私有化,所以C#中virtual关键字和private关键字不能同时使用。
其二:因为静态的方法和抽象方法不能重写,同理C#中static,abstract关键字和virtual关键字不能同时使用。
其三:不能在声明虚方法的同时指定重写虚方法,因为重写方法只能重写基类的虚方法,也就是要提前在基类中声明虚方法,所以virtual关键字和override关键字不能同时使用。
2.静态方法:
使用了static 修饰符的方法为静态方法,反之则是非静态方法。
静态方法是一种 特殊的成员方法,它不属于类的某一个具体的实例,而是属于类本身。
所以对静态方法不需要 首先创建一个类的实例,而是采用类名.静态方法的格式 。
1.static方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用!
static内部只能出现static变量和其他static方法!而且static方法中还不能使用this....等关键字..因为它是 属于整个类!
2.静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。
3.静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存.
4.静态方法代码只有一份,它们的生命周期和类是一致的.实例方法是通过对象名调用的,调用结束,就会被GC回收。
5.那么在程序中什么地方可以用静态字段和静态构造方法?通常适用于于一些不会经常变化而又频繁使用的数据,比如连接字符串,配置信息等,当满足上面所 说的两点时,进行一次读取,以后就可以方便的使用了,同时也节约了托管资源,因为对于静态成员,一个静态字段只标识一个存储位置。因为对一个类无论创建了多少个实例,它的静态字段永远都只有一个副本(副本我理解为只有一块内存 ,静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员(因为非静态成员可能没有被分配空间,还不存在呢);反之非静态成员可以直接访问类中静态的成员(因为只要类存在,这个静态方法就存在).
3.实例方法:
早期的结构化编程,几乎所有的方法都是“静态方法”,而直到面向对象编程语言来临时,才被区分为了实例化方法和静态方法。而这样的区分,并不是单一从性能的角度进行考虑的,而是为了让开发更加模式化,面向对象化。
比如说人这个类,姓名、年龄等这些属性就必须是实例化属性,而所属科目,比如灵长类,则一定是静态属性,因为这个属性并不依赖于某一个人
总结下来,静态方法用在与类中属性无关的函数,而实例化方法用在与类中属性有关的函数。而在真实的实践当中也证明,静态方法的调用并不比实例化方法效率更高