C#之(Virtual)虚拟与(abstract)抽象
在上篇我们讲解了override(重写)与overload(重载),里面涉及到了虚拟方法和抽象方法,所以我们现在重点把(Virtual)虚拟与(abstract)抽象,在这里给大家详细讲解一下
override(重写)与overload(重载)详解
一,(Virtual)虚拟
- 在 C# 语言中,virtual是虚拟的含义,默认情况下类中的成员都是非虚拟的.
- 我们将类中的成员定义成虚拟的,表示这些成员将会在继承后重写其中的内容。
- virtual 关键字能修饰方法、属性、索引器以及事件等,运用在父类的成员中。
virtual 的语法
virtual关键字修饰属性
//修饰属性
public virtual 数据类型 属性名{get; set; }
virtual关键字修饰方法
//修饰方法
访问修饰符 virtual 返回值类型 方法名
{
语句块;
}
virtual的案例
- (虚拟方法)在父类中创建虚拟(virtual)方法
class A
{
//虚拟方法;关键字virtual
public virtual void dog()//虚拟方法
{
Console.WriteLine("父类中的虚拟方法:我叫哈士奇");
}
public virtual void cat()//虚拟方法
{
Console.WriteLine("父类中的虚拟方法:我叫小猫咪");
}
public void eat()//普通方法
{
Console.WriteLine("我是哈爷,我爱吃空气");
}
}
- 虚拟方法)在子类继承父类之后,我们对父类中的虚拟方法进行重写(override)
- 重写以后子类就会将父类中的虚拟方法进行覆盖,最后的结果不会显示父类中的方法,只会显示我们在子类重写以后的方法
- 除非我们输入(base.[父类中的方法名称])父类的方法就不会被覆盖,依旧可以显示
class B:A
{
public override void dog()//重写的虚拟方法
{
base.dog();//重写以后如果想调用父类中的方法则输入base.[父类中的方法名称]
Console.WriteLine("子类中重写以后的方法:我改名了,我叫哈爷");
}
public override void cat()//重写的虚拟方法
{
base.cat();//重写以后如果想调用父类中的方法则输入base.[父类中的方法名称]
Console.WriteLine("子类中重写以后的方法:我也改名了,我叫瞄崽");
}
}
- (虚拟方法)在主程序入口实例化子类进行调用
class Program
{
static void Main(string[] args)
{
B cx = new B();//实例化子类
//调用虚拟方法
cx.dog();
cx.cat();
cx.eat();
Console.ReadLine();
}
}
- 虚拟方法)没有输入(base.[父类中的方法名称])的显示结果
子类中重写以后的方法:我改名了,我叫哈爷
子类中重写以后的方法:我也改名了,我叫瞄崽
我是哈爷,我爱吃空气
- (虚拟方法)输入(base.[父类中的方法名称])的显示结果
父类中的虚拟方法:我叫哈士奇
子类中重写以后的方法:我改名了,我叫哈爷
父类中的虚拟方法:我叫小猫咪
子类中重写以后的方法:我也改名了,我叫瞄崽
我是哈爷,我爱吃空气
注意事项;
- virtual 关键字不能修饰使用 static 修饰的成员。
- virtual 关键字既可以添加到访问修饰符的后面,也可以添加到访问修饰符的前面,但实际应用中习惯将该关键字放到访问修饰符的后面。
二,(abstract)抽象
- C# abstract 关键字代表的是抽象的,使用该关键字能修饰类和方法,修饰的方法被称为抽象方法、修饰的类被称为抽象类
abstract语法
在 C# 语言中抽象方法是一种不带方法体的方法,仅包含方法的定义,语法形式如下。
- 其中,当 abstract 用于修饰方法时,也可以将 abstract 放到访问修饰符的前面。
- 抽象方法定义后面的“;”符号是必须保留的。需要注意的是,抽象方法必须定义在抽象类中。
访问修饰符 abstract 方法返回值类型 方法名(参数列表);
在定义抽象类时,若使用 abstract 修饰类,将其放到 class 关键字的前面,语法形式如下。
- 其中“abstract”关键字也可以放到访问修饰符的前面。
访问修饰符 abstract class 类名
{
//类成员
}
abstract的案例
- (抽象方法)在父类中创建抽象(abstract)方法
- 一旦一个方法被声明为抽象方法(abstract)则该方法不能有主体(具体的实现)
- 而且该方法所对应的类,必须是抽象的类
abstract class A
{
//抽象方法;关键字abstract
public abstract void Junk();//抽象方法
public abstract void He();//抽象方法
}
- 抽象方法)在子类继承父类之后,我们对父类中的抽象方法进行重写(override)
- 一个子类继承了一个抽象类,那么子类必须重写父类中所有的抽象方法
class B:A
{
public override void Junk()
{
Console.WriteLine("子类中重写的抽象方法我喜欢喝可乐");
}
public override void He()
{
Console.WriteLine("子类中重写的抽象方法:我喜欢喝雪碧");
}
}
- (抽象方法)在主程序入口实例化子类进行调用
class Program
{
static void Main(string[] args)
{
B cx = new B();//实例化子类
//调用抽象方法
cx.Junk();
cx.He();
Console.ReadLine();
}
}
- (抽象方法)最后的显示结果为
子类中重写的抽象方法我喜欢喝可乐
子类中重写的抽象方法:我喜欢喝雪碧
注意事项;
- 在抽象类中可以定义抽象方法,也可以定义非抽象方法。
- 通常抽象类会被其他类继承,并重写其中的抽象方法或者虚方法。
- 此外,尽管在抽象类中仍然能定义构造器,但抽象类不能实例化,即不能使用如下语句。
new 抽象类的名称();
- 在实际应用中,子类仅能重写父类中的虚方法或者抽象方法,当不需要使用父类中方法的内容时,将其定义成抽象方法,否则将方法定义成虚方法。
(Virtual)虚拟方法与(abstract)抽象方法的区别?
虚拟方法和抽象方法都可以供派生类重写和都用override重写。那么它们之间有什么区别呢?
-
抽象方法使用abstract关键字,虚拟方法使用virtual关键字
-
抽象方法是可以看成是没有实现体的虚拟方法
-
虚拟方法与多态性关系密切,虚拟方法为子类提供了重写该方法的选项允许子类完全或部分重写该类的方法,必须写方法体。
抽象方法只是一个定义,没有提供实现部分,也就是没有{},也不要在里面写内容,需要在子类中实现,抽象方法是一种强制子类重写的方法,否则子类将不能被实例化。
-
抽象方法必须在派生类中重写,这一点跟接口类似,虚拟方法不必。
-
抽象方法不能声明方法体,而虚拟方法可以。
-
抽象类不能被实例化(不可以new),只能实例化实现了全部抽象方法的派生类;而包含虚方法的类可以实例化。
-
虚拟方法是指能被重载覆盖的方法,而抽象方法是虚拟方法中的特例,指完全没有具体实现的虚拟方法.
-
如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其它一般方法
-
抽象方法是必须被派生类覆写的方法,调用虚拟方法,运行时将确定调用对象是什么类的实例,并调用适当的覆写的方法
-
.一个虚拟方法的实现可以由派生类取代。取代所继承的虚拟方法的实现的过程称为重写该方法;在一个虚拟方法调用中,该调用所涉及的那个实例的运行时类型确定了要被调用的究竟是该方法的哪一个实现。
-
抽象方法是需要子类去实现的.虚方法,是已经实现了,子类可以去覆盖,也可以不覆盖取决于需求.
看过以后有什么问题,请及时留言,本人会及时改正
感觉还不错的点波关注,以后会陆续更新新的疑难杂症.