C#继承的多态性

当一个类A派生出新类B时,这个基类A在新类B中可以表现为不同的类型:用作它自己的类型、基类型,或者在实现接口时用作接口类型,我们将这种情况称为多态性。

C#中的每种类型都是多态性的,都可以用作它们自己的类型或者用作Object实例,因为所有的类型都自动将Object当做基类型。

基类的设计者可以预测到其基类中可能会在派生类中发生更改的方面。比如,表示汽车的基类可能包含这样的行为:当考虑的汽车为小型货车或敞蓬汽车时,这些行为将会改变。基类可以将这些类成员标记为虚拟的,从而允许表示小型货车和敞蓬汽车的派生类重写该行为。

当派生类从基类继承时,它会获得基类的所有方法、字段、属性和事件。

提示:当派生类成员所需要的数据类型和行为与基类中同名成员的数据类型和行为不一致时,我们就需要在派生类中修改基类中同名成员的数据类型和行为了。前面文章中讲的继承都是指同名成员的数据类型和行为完全一致的情况下的继承,在这里讲的是不一致的情况下的继承的方法。

要更改基类的数据和行为,有两种选择:可以使用新的派生成员替换基类的成员,或者可以重写虚拟的基类成员。

一、使用新的派生成员替换基类的成员

使用new关键字可以让新的派生成员替换基类中的同名成员。如果基类中定义了一个方法、字段或属性,则可以使用new关键字在派生类中创建该方法、字段或属性的新定义。

例如,在基类中定义一个方法、字段或属性:
 
public class A
{
    public void Method(){ }
    public int Field;
    public int Property;
    {
        get{return 0;}
    }
}

下面在派生类中创建该方法、字段或属性的新定义:
 
public class B : A
{
    public new void Method(){ }
    public new int Field;
    public new int Property;
    {
        get{return 0;}
    }
}

使用new关键字时,调用的是新的类成员而不是已被替换的基类成员。这些基类成员称为隐藏成员。

如果将派生类的实例强制转换为基类的实例,就仍然可以调用隐藏类成员。

例如:
 
B b = new B();
b.Method();   // 调用派生类中的新方法
A a = (A)b;   // 将派生类B的实例b强制转换为基类A的实例a
a.Method();   // 调用基类中的旧方法二、重写虚拟的基类成员
1. 使用virtual关键字重写虚拟的基类成员

使用virtual关键字可以将基类中的成员声明为虚拟的,以便让派生类的实例完全接替来自基类的该类成员。然后,派生类可以使用override关键字将基类实现替换为它自己的实现。

例如,将基类中的成员声明为虚拟的:

public class A
{
    public virtual void Method(){ }
    public virtual int Property;
    {
        get{return 0;}
    }
}在派生类中替换为它自己的实现:

public class B : A
{
    public override void Method(){ }
    public override int Property;
    {
        get{return 0;}
    }
}
 
2. 示例
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    class Program
    {
        public class A
        {
            public virtual void AAA()
            {
                Console.WriteLine("基类A");
            }
        }
        class B : A
        {
            public override void AAA()
            {
                Console.WriteLine("派生类B");
                base.AAA();
            }
        }
        class C : A
        {
            public override void AAA()
            {
                Console.WriteLine("派生类C");
                base.AAA();
            }
        }
        class D : A
        {
            public override void AAA()
            {
                Console.WriteLine("派生类D");
                base.AAA();
            }
        }
        static void Main(string[] args)
        {
            // C#重写虚拟的基类成员-www.baike369.com
            System.Collections.Generic.List<A> a = 
                new System.Collections.Generic.List<A>();
            a.Add(new B());
            a.Add(new C());
            a.Add(new D());
            foreach (A i in a)
            {i.AAA();}
            Console.WriteLine("请按任意键退出!");
            Console.ReadKey();
        }
    }
}

运行结果:
 
派生类B
基类A
派生类C
基类A
派生类D
基类A

请按任意键退出!在基类中可以定义并实现虚方法,派生类可以重写这些方法,就是指派生类可以提供自己的定义和实现。

C#继承的多态性的更多相关文章

  1. Object与封装、继承和多态性

    Object与封装.继承和多态性 在面向对象编程思想中,无论是C++,Java还是C#等,封装.继承与多态性都有着无与伦比的地位,深入理解并掌握它们是必不可少的.而我将使用C#来浅谈继承与多态性. 1 ...

  2. javaScript的原型继承与多态性

    1.prototype 我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉 ...

  3. C++的三大特性:封装、继承和多态性的详解

    封装 所谓封装就是将某些东西包装盒隐藏起来,让外界无法直接使用,只能通过某些特定的方式才能访问.封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是通过外部接口以及特定的访问权限来使 ...

  4. C++ 三大特性:封装、继承、多态性

    要讲  封装.继承.多态就必须从面向对象说起 开发一个软件是为了解决某些问题,这些问题所涉及的业务范围称为该软件的问题域.面向对象的编程语言将客观事物看作具有属性和行为(或服务)的对象,通过抽象找出同 ...

  5. 类的继承和多态性-编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 getLegs(),设置动物名称的方法 setKind(),获得动物名称的方法 getKind(),获得动物数量的方法 getCount()。定义Fish类,是Animal类的子类,

    编写Java应用程序,定义Animal类,此类中有动物的属性:名称 name,腿的数量legs,统计动物的数量 count;方法:设置动物腿数量的方法 void setLegs(),获得腿数量的方法 ...

  6. SV 类继承的多态性问题(NVDIA2019笔试)

    1.原题 class class_a; virtual function void print_name(); $display("this is class_a"); endfu ...

  7. Py修行路 python基础 (十六)面向对象编程的 继承 多态与多态性 封装

    一.继承顺序: 多继承情况下,有两种方式:深度优先和广度优先 1.py3/py2 新式类的继承:在查找属性时遵循:广度优先 继承顺序是多条分支,按照从左往右的顺序,进行一步一步查找,一个分支走完会走另 ...

  8. C# 一些知识点总结(一)_继承,多态,集合,关键字...

    内存中的三大存储区域:栈.堆.静态存储区域 new 关键字:new帮助我们做了三件事:1)在内存中开辟一块空间(开辟内存空间)2) 在开辟的空间中创建对象3)调用对象的构造函数进行初始化对象所以构造函 ...

  9. java面向对象(二)之继承

    继承 介绍 继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力.继承即常说的is-a关系.子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承 ...

随机推荐

  1. c++中 重载 覆盖 隐藏的区别 附加 mutable笔记

    成员函数被重载的特征有: 1) 相同的范围(在同一个类中): //2) 函数名字相同: 3) 参数不同: 4) virtual关键字可有可无. 覆盖的特征有: 1) 不同的范围(分别位于派生类与基类) ...

  2. python dataframe drop_duplicates用法技巧去重

    data.drop_duplicates()#data中一行元素全部相同时才去除 data.drop_duplicates(['a','b'])#data根据’a','b'组合列删除重复项,默认保留第 ...

  3. HDU 5592——ZYB's Premutation——————【线段树单点更新、单点查询】

    ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  4. netty之==TCP粘包/拆包问题解决之道(一)

    一.TCP粘包/拆包是什么 TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在 ...

  5. 了解委托(Delegate)

    委托是一种全新面向对象语言特性,运行在.Net平台 基于委托,开发事件驱动程序变得非常简单 使用委托可以大大简化多线程变成的难度 理解委托 int a:   //定义变量 a=100://给变量赋值 ...

  6. vue学习第一天 ------ 临时笔记

    学习链接 Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(一)基础知识概述 http://blog.csdn.net/fungleo/article/detai ...

  7. 设置 text-align: center;line-height:height 居中无效

    1.设置文字水平居中 内联元素(行内元素)使用: text-align: center: 使用后文字仍然没有居中 解决方法:设置width:100%: 块元素使用: margin: 0 auto; 2 ...

  8. CSS 属性之中经常出现的百分比(转)

    CSS 的属性值中经常会出现百分比,搞清它们的基数是一件很重要的事情.我特意查看了一下 W3C 的 CSS2.1 标准,在此整理下: 百分比单位 乘以包含块的宽度 margin, padding, l ...

  9. 浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架

    简介 SQL Server中的事务日志无疑是SQL Server中最重要的部分之一.因为SQL SERVER利用事务日志来确保持久性(Durability)和事务回滚(Rollback).从而还部分确 ...

  10. artTemplate教程

    artTemplate教程 官方文档 一个简单的例子 <!DOCTYPE html> <html lang="zh"> <head> <m ...