搜索

C# 多态性

Feb 16, 2017 am 11:12 AM


转载自:MSDN

类似文章:点击打开链接

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

  •  发生此情况时,该对象的声明类型不再与运行时类型相同。

  •  在运行时,客户端代码调用该方法,CLR 查找对象的运行时类型,并调用虚方法的重写方法。 因此,你可以在源代码中调用基类的方法,但执行该方法的派生类版本。

  • 派生类(子类)与基类(父类)之间强制转换不会丢失信息。

  • namespace PolymorphismTest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            private void button1_Click(object sender, EventArgs e)
            {
                ParentClass parent = new ParentClass();
                SubClass sub = new SubClass();
                parent = ((ParentClass)sub);
                //子类 父类 实例之间来回转换不会丢失信息
               SubClass subNew = (SubClass)parent;
            }
        }
        public class SubClass : ParentClass
        {
            public new string name = "SubClass";
            public int age = 20;
        }
        public class ParentClass
        {
            string name = "ParentClass"; 
        }
    }

    执行到

    SubClass subNew = (SubClass)parent

    具体结果如下图:



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

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

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

 为 Shape 类提供一个名为 Draw 的虚方法,并在每个派生类中重写该方法以绘制该类表示的特定形状。创建一个 List5c58ee79afe736c10ab537fb5aaf549d 对象,并向该对象添加 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.List5c58ee79afe736c10ab537fb5aaf549d shapes = new System.Collections.Generic.List5c58ee79afe736c10ab537fb5aaf549d();
        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中文网(www.php.cn)!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
c#vs. .net:澄清关键差异和相似之处c#vs. .net:澄清关键差异和相似之处May 01, 2025 am 12:12 AM

C#是一种编程语言,而.NET是一个软件框架。1.C#由微软开发,适用于多平台开发。2..NET提供类库和运行时环境,支持多语言。两者协同工作,构建现代应用。

超越炒作:评估C#.NET的当前作用超越炒作:评估C#.NET的当前作用Apr 30, 2025 am 12:06 AM

C#.NET是一个强大的开发平台,结合了C#语言和.NET框架的优势。1)它广泛应用于企业应用、Web开发、游戏开发和移动应用开发。2)C#代码编译成中间语言后由.NET运行时环境执行,支持垃圾回收、类型安全和LINQ查询。3)使用示例包括基本控制台输出和高级LINQ查询。4)常见错误如空引用和类型转换错误可以通过调试器和日志记录解决。5)性能优化建议包括异步编程和优化LINQ查询。6)尽管面临竞争,C#.NET通过不断创新保持其重要地位。

C#.NET的未来:趋势和机遇C#.NET的未来:趋势和机遇Apr 29, 2025 am 12:02 AM

C#.NET的未来趋势主要集中在云计算、微服务、AI和机器学习集成以及跨平台开发三个方面。1)云计算和微服务:C#.NET通过Azure平台优化云环境表现,支持构建高效微服务架构。2)AI和机器学习集成:借助ML.NET库,C#开发者可在应用中嵌入机器学习模型,推动智能化应用发展。3)跨平台开发:通过.NETCore和.NET5 ,C#应用可在Windows、Linux和macOS上运行,扩展部署范围。

C#.NET开发今天:趋势和最佳实践C#.NET开发今天:趋势和最佳实践Apr 28, 2025 am 12:25 AM

C#.NET开发的最新动态和最佳实践包括:1.异步编程提高应用响应性,使用async和await关键字简化非阻塞代码;2.LINQ提供强大查询功能,通过延迟执行和表达式树高效操作数据;3.性能优化建议包括使用异步编程、优化LINQ查询、合理管理内存、提升代码可读性和维护性、以及编写单元测试。

C#.NET:使用.NET生态系统构建应用程序C#.NET:使用.NET生态系统构建应用程序Apr 27, 2025 am 12:12 AM

如何利用.NET构建应用?使用.NET构建应用可以通过以下步骤实现:1)了解.NET基础知识,包括C#语言和跨平台开发支持;2)学习核心概念,如.NET生态系统的组件和工作原理;3)掌握基本和高级用法,从简单控制台应用到复杂的WebAPI和数据库操作;4)熟悉常见错误与调试技巧,如配置和数据库连接问题;5)应用性能优化与最佳实践,如异步编程和缓存。

C#作为多功能.NET语言:应用程序和示例C#作为多功能.NET语言:应用程序和示例Apr 26, 2025 am 12:26 AM

C#在企业级应用、游戏开发、移动应用和Web开发中均有广泛应用。1)在企业级应用中,C#常用于ASP.NETCore开发WebAPI。2)在游戏开发中,C#与Unity引擎结合,实现角色控制等功能。3)C#支持多态性和异步编程,提高代码灵活性和应用性能。

C#.NET用于网络,桌面和移动开发C#.NET用于网络,桌面和移动开发Apr 25, 2025 am 12:01 AM

C#和.NET适用于Web、桌面和移动开发。1)在Web开发中,ASP.NETCore支持跨平台开发。2)桌面开发使用WPF和WinForms,适用于不同需求。3)移动开发通过Xamarin实现跨平台应用。

C#.NET生态系统:框架,库和工具C#.NET生态系统:框架,库和工具Apr 24, 2025 am 12:02 AM

C#.NET生态系统提供了丰富的框架和库,帮助开发者高效构建应用。1.ASP.NETCore用于构建高性能Web应用,2.EntityFrameworkCore用于数据库操作。通过理解这些工具的使用和最佳实践,开发者可以提高应用的质量和性能。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。