C#中的屏蔽、覆写和抽象

屏蔽基类成员

虽然派生类不能删除其继承的任何成员,但可以声明一个与基类成员签名相同的成员来屏蔽之。(注意方法的签名由名称和参数列表组成,不包括返回值类型)

要让编译器知道你在故意屏蔽继承的成员,可使用new操作符,否则会出现警告。

namespace TestConsole
{
    class Human
    {
        public void Action()
        {
            Console.WriteLine("labour...");
        }
    }

    class Student : Human
    {
        new public void Action()
        {
            Console.WriteLine("studing...");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Student stu1 = new Student();
            stu1.Action(); //运行结果为:studing...
            
            Human stu2 = new Student();
            stu2.Action(); //运行结果为:labour...
        }
    }
}

可以看到,如果是用基类类型来创建子类对象,就无法实现屏蔽,除非使用虚方法和覆写方法。

虚方法和覆写方法

虚方法即是基类中被标记为virtual的方法,在派生类中有与之对应的override方法,被称为覆写方法,或重写方法。多态就是基于重写机制的。

namespace TestConsole
{
    class Human
    {
        public virtual void Action()
        {
            Console.WriteLine("labour...");
        }
    }

    class Student : Human
    {
        public override void Action()
        {
            Console.WriteLine("studing...");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Student stu1 = new Student();
            stu1.Action(); //运行结果为:studing...

            Human stu2 = new Student();
            stu2.Action(); //运行结果为:studing...
        }
    }
}

关于virtual和override修饰符有以下注意事项:

  • 虚方法和与之对应的覆写方法必须有相同的可访问性,不能一个public而另一个private。
  • 不能覆写static方法或非虚方法。
  • 方法、属性、索引器、事件,都可以被声明为virtual和override。

抽象类与抽象成员

如果基类中存在这样一个方法,该基类没有实现它的意义,是专门用来给子类实现的,那么我们可以将其声明为抽象成员。

抽象成员是专门用来被覆写的成员,其有以下特征:

  • 必须是一个函数成员,即常量和字段不能声明为抽象成员。
  • 没有实现代码块,抽象成员的实现代码部分仅用一个分号表示。
  • 必须用abstract修饰符标记。
  • 不能是私有成员,可以是public或protected。
  • 只能在抽象类中声明。

抽象成员在C++中被称为纯虚函数,因为相比普通的虚函数,其连实现代码块都没有。相比虚方法,抽象成员必须被覆写,前者覆写是可选的,而后者是必须的。

有4种类型的成员可以声明为抽象成员:方法、属性、事件、索引器。

抽象类则是专门用来被继承的类,抽象类只能被用作其他类的基类,其不能创建实例对象,且要和抽象成员一样,使用abstract声明。抽象类中可以包含抽象成员或非抽象成员,但抽象成员只能存在于抽象类中。

namespace TestConsole
{
    abstract class Animal
    {
        public abstract void Action();
    }
    
    class Human : Animal
    {
        public override void Action()
        {
            Console.WriteLine("labour...");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Human man = new Human();
            man.Action();
        }
    }
}

抽象类与开闭原则

SOLID设计原则中的“开闭原则”:如果不是为了修复bug或增加功能,尽量不要去修改类的代码,特别是函数成员的代码;我们应该封装那些稳定的、确定的、不变的成员,而那些不稳定的、不确定的、随时可能会改变的成员应该声明为抽象成员,留给子类去实现。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值