[C#] virtual和abstract

0 声明

本人对于virtual以及abstract的认识还有所不足,下文的某些言论可能认识不成熟。请大家理性看待。

1 virtural

1.1 virtual

virtural意为虚拟的。和override关键字配合实现面向对象中的重写,进而实现多态。只能应用于方法中。

namespace test;

public class Animal
{
    public virtual void eat()
    {
        Console.WriteLine("animial eat");
    }
}
namespace test;

public class Dog:Animal
{
    public override void eat()
    {
        Console.WriteLine("dog eat");
    }
}
namespace test;

public class Cat : Animal
{
    public override void eat()
    {
        Console.WriteLine("cat eat");
    }
}
public class Test
{
    public static void Main()
    {
        Animial[] animal = new Animial[3];
        animal[0] = new Animal();
        animal[1] = new Dog();
        animal[2] = new Cat();
        for (int i = 1; i < 3; i++)
        {
            animal[i].eat();
        }
    }
}

输出:
animial eat
dog eat
cat eat

上面的例子是多态的一个展示——

  1. 通过将基类引用指向派生类对象
  2. 并调用重写的方法

一个方法展现出多种状态,即为多态。

1.2 与方法隐藏的区别

方法隐藏与重写的区别在于去掉了override,即派生类中有一个与基类中待重写方法一模一样的方法。这并不能实现多态。

上述例子中的输出会变成

输出:
animial eat
animal eat
animal eat

1.3 方法调用的原理

待续

2 abstract

abstract可以用于类和方法中。

与virtual关键字区别如下:

  1. abstract可以用于类中,意为抽象,有两层意思——第一,表示不可被实例化,因为没有实际用途(仅仅声明一个动物类,很难产生实际作用,需要派生类来实际产生作用;若有需要也可不声明为抽象类);第二,表示同类物体的共性。
  2. abstract还可用于abstract类中的方法。此时方法没有方法体,必须在派生类中重写。
  3. abstract中的正常方法:abstract类中的方法也可以不用abstract关键字修饰,如同正常方法一样,但只能被子类继承后调用。
  4. 总结2和3可得:abstract类中的方法,有些是没有差异的共性(3),有些是有差异的共性(2)。

如下是抽象的展示

namespace test;

public abstract class Animal
{
	//动物吃饭的方式不尽相同,所以声明为抽象的,让派生类自己决定
    public abstract void eat();
    //从人的视角看,每个动物都有一个名字,所以Name属性不加abstract。
    //为了保险起见(万一获取/设置动物的名字方式不同),可以加virtual以备重写
    public string Name { get; set; }

    public void NormalFunc()
    {
        Console.WriteLine("NormalFunc");
    }

}
namespace test;

public class Cat : Animal
{
    public override void eat()
    {
        Console.WriteLine("cat eat");
    }
}
namespace test;

public class Dog:Animal
{
    public override void eat()
    {
        Console.WriteLine("dog eat");
    }
}
namespace test;

public class Test
{
    public static void Main()
    {
    	//错误,抽象类不可被实例化
    	//Animal animal = new Animal(); 
    	//声明一个引用是可以的
        Animal[] animal = new Animal[3];
        animal[1] = new Dog();
        animal[2] = new Cat();
        for (int i = 1; i < 3; i++)
        {
            animal[i].eat();
        }
    }
}
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值