• 技术文章 >后端开发 >C#.Net教程

    C# 多态性

    黄舟黄舟2017-02-16 11:12:43原创887


    转载自:MSDN

    类似文章:点击打开链接

    Polymorphism(多态性)是一个希腊词,指“多种形态”,多态性具有两个截然不同的方面:

    例如,假定你有一个绘图应用程序,允许用户在绘图图面上创建各种形状。 你在编译时不知道用户将创建哪些特定类型的形状。 但应用程序必须跟踪创建的所有类型的形状,并且必须更新这些形状以响应用户鼠标操作。 你可以使用多态性通过两个基本步骤解决这一问题:

    1. 创建一个类层次结构,其中每个特定形状类均派生自一个公共基类。

    2. 使用虚方法通过对基类方法的单个调用来调用任何派生类上的相应方法。

    Shape 类提供一个名为 Draw 的虚方法,并在每个派生类中重写该方法以绘制该类表示的特定形状。创建一个 List<Shape> 对象,并向该对象添加 Circle、Triangle 和 Rectangle。 若要更新绘图图面,请使用 foreach 循环对该列表进行循环访问,并对其中的每个 Shape 对象调用 Draw 方法。 虽然列表中的每个对象都具有声明类型 Shape,但调用的将是运行时类型(该方法在每个派生类中的重写版本)。




    C#





    public class Shape
    {    // A few example members 
        public int X { get; private set; }    public int Y { get; private set; }    public int Height { get; set; }    public int Width { get; set; }    // Virtual method 
        public virtual void Draw()
        {
            Console.WriteLine("Performing base class drawing tasks");
        }
    }class Circle : Shape
    {    public override void Draw()
        {        // Code to draw a circle...
            Console.WriteLine("Drawing a circle");        base.Draw();
        }
    }class Rectangle : Shape
    {    public override void Draw()
        {        // Code to draw a rectangle...
            Console.WriteLine("Drawing a rectangle");        base.Draw();
        }
    }class Triangle : Shape
    {    public override void Draw()
        {        // Code to draw a triangle...
            Console.WriteLine("Drawing a triangle");        base.Draw();
        }
    }class Program
    {    static void Main(string[] args)
        {        // Polymorphism at work #1: a Rectangle, Triangle and Circle 
            // can all be used whereever a Shape is expected. No cast is 
            // required because an implicit conversion exists from a derived  
            // class to its base class.
            System.Collections.Generic.List<Shape> shapes = new System.Collections.Generic.List<Shape>();
            shapes.Add(new Rectangle());
            shapes.Add(new Triangle());
            shapes.Add(new Circle());        // Polymorphism at work #2: the virtual method Draw is 
            // invoked on each of the derived classes, not the base class. 
            foreach (Shape s in shapes)
            {
                s.Draw();
            }        // Keep the console open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    
    }/* Output:
        Drawing a rectangle
        Performing base class drawing tasks
        Drawing a triangle
        Performing base class drawing tasks
        Drawing a circle
        Performing base class drawing tasks
     */

    在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。

    关注对象原则:调用子类还是父类的方法,取决于创建的对象是子类对象还是父类对象

    多态性概述



    虚成员



    派生类的设计器可以选择是否

    派生成员必须使用 override 关键字显式指示该方法将参与虚调用。 以下代码提供了一个示例:




    C#





    public class BaseClass
    {    public virtual void DoWork() { }    public virtual int WorkProperty
        {        get { return 0; }
        }
    }public class DerivedClass : BaseClass
    {    public override void DoWork() { }    public override int WorkProperty
        {        get { return 0; }
        }
    }

    当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员。 以下代码提供了一个示例:




    C#





    DerivedClass B = new DerivedClass();
    B.DoWork();  // Calls the new method.BaseClass A = (BaseClass)B;
    A.DoWork();  // Also calls the new method.

    有关详细信息,请参阅使用 Override 和 New 关键字进行版本控制(C# 编程指南)。 接口提供另一种方式来定义将实现留给派生类的方法或方法集。 有关详细信息,请参阅接口(C# 编程指南)。

    使用新成员隐藏基类成员



    new 关键字放置在要替换的类成员的返回类型之前。 以下代码提供了一个示例:




    C#





    public class BaseClass
    {    public void DoWork() { WorkField++; }    public int WorkField;    public int WorkProperty
        {        get { return 0; }
        }
    }public class DerivedClass : BaseClass
    {    public new void DoWork() { WorkField++; }    public new int WorkField;    public new int WorkProperty
        {        get { return 0; }
        }
    }

    例如:




    C#





    DerivedClass B = new DerivedClass();
    B.DoWork();  // Calls the new method.BaseClass A = (BaseClass)B;
    A.DoWork();  // Calls the old method.

    阻止派生类重写虚拟成员



    如果类 A 声明了一个虚拟成员,类 B 从 A 派生,类 C 从类 B 派生,则类 C 继承该虚拟成员,并且可以选择重写它,而不管类 B 是否为该成员声明了重写。 以下代码提供了一个示例:




    C#





    public class A
    {    public virtual void DoWork() { }
    }public class B : A
    {    public override void DoWork() { }
    }

    这需要在类成员声明中的 override 关键字前面放置 sealed 关键字。 以下代码提供了一个示例:




    C#





    public class C : B
    {    public sealed override void DoWork() { }
    }

    即使它们转换为类型 B 或类型 A,它对于 C 的实例仍然是虚拟的。 通过使用 new 关键字,密封的方法可以由派生类替换,如下面的示例所示:




    C#





    public class D : C
    {    public new void DoWork() { }
    }

    如果使用类型为 C、B 或 A 的变量访问 D 的实例,对 DoWork 的调用将遵循虚拟继承的规则,即把这些调用传送到类 C 的 DoWork 实现。

    从派生类访问基类虚拟成员



    以下代码提供了一个示例:




    C#





    public class Base
    {    public virtual void DoWork() {/*...*/ }
    }public class Derived : Base
    {    public override void DoWork()
        {        //Perform Derived's work here 
            //... 
            // Call DoWork on base class 
            base.DoWork();
        }
    }

    有关详细信息,请参阅 base。

    说明 说明

    允许基类行为发生使得派生类能够集中精力实现特定于派生类的行为。 未调用基类实现时,由派生类负责使它们的行为与基类的行为兼容。

    以上就是C# 多态性的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:C# ,多态性
    上一篇:C# 字符串中多个连续空格转为一个空格 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • c语言中goto语句的含义是什么• 应用绝对路径与相对路径• 【c#教程】C# 属性(Property)• ASP.NET使用Ajax如何返回Json对象的方法具体介绍• C/C++深度分析
    1/1

    PHP中文网