English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
التباين هو القدرة على أن يكون لدى نفس السلوك عدة تعبيرات أو أشكال مختلفة.
التباينيعني أنه هناك أنواع متعددة. في نموذج البرمجة الموجه للأغراض، يظهر التباين غالبًا كـ "واجهة واحدة، عدة وظائف".
يمكن أن يكون التباين ثابتًا أو ديناميكيًا. فيالتباين الثابتفيها، يحدث الاستجابة للوظيفة في وقت التجميع. في动态多态性فيها، يحدث الاستجابة للوظيفة في وقت التشغيل.
في C#، كل نوع هو متباين، لأن جميع الأنواع، بما في ذلك الأنواع المحددة من قبل المستخدم، تنحدر من Object.
التباين هو نفس الواجهة، باستخدام مختلف الأمثلة لت�行واع مختلفة، كما هو موضح في الشكل:
في الحياة الواقعية، مثل الضغط على مفتاح F1 هذا الحركة:
إذا كانت النافذة المنبثقة في واجهة Flash، فإنها ستكون وثائق المساعدة لـ AS 3;
إذا كانت النافذة المنبثقة في Word، فإنها ستكون مساعدة Word;
في Windows، سيكون النافذة المنبثقة مساعدة Windows ودعمها.
يمكن أن تكون النتائج المختلفة عند حدوث نفس الحدث على مختلف الأغراض.
في وقت التجميع، يُسمى نظام الاتصال بين الدوال والأغراض بـ 'الربط المبكر' أو 'الربط الثابت'. يقدم C# نوعين من التكنولوجيا لتحقيق التباين الثابت. وهي:
تحميل الدوال
تحميل العمليات
سيتم مناقشة تحميل العمليات في الفصل القادم، حيث سنناقش تحميل الدوال.
يمكنك تعريف أكثر من تعريف للوظيفة نفسها في نفس النطاق. يجب أن تكون التعريفات المختلفة مختلفة، يمكن أن تكون أنواع المعلمات المختلفة في قائمة المعلمات، أو يمكن أن تكون أعداد المعلمات المختلفة. لا يمكن أن تكون هناك تعريفات متعددة فقط من خلال إعلان نوع العودة المختلف.
下面的示例演示了几个相同的函数 Add()،لإجراء عمليات إضافة مختلفة للعدد المختلفة من المعلمات:
using System; namespace PolymorphismApplication } public class TestData } public int Add(int a, int b, int c) } return a + b + c; } public int Add(int a, int b) } return a + b; } } class Program } static void Main(string[] args) } TestData dataClass = new TestData(); int add1 = dataClass.Add(1, 2); int add2 = dataClass.Add(1, 2, 3); Console.WriteLine("add1 : " + add1); Console.WriteLine("add2 : " + add2); } } }
下面的示例演示了几个相同的函数 print(),用于打印不同的数据类型:
using System; namespace PolymorphismApplication } class Printdata } void print(int i) } Console.WriteLine("输出整型: {0}", i); } void print(double f) } Console.WriteLine("输出浮点型: {0}", f); } void print(string s) } Console.WriteLine("输出字符串: {0}", s); } static void Main(string[] args) } Printdata p = new Printdata(); // 调用 print 来打印整数 p.print(1); // 调用 print 来打印浮点数 p.print(1.23); // 调用 print 来打印字符串 p.print("Hello w3codebox"); Console.ReadKey(); } } }
عندما يتم تجميع وكتابة وتنفيذ الكود أعلاه، سيظهر النتيجة التالية:
输出整型: 1 输出浮点型: 1.23 输出字符串: Hello w3codebox
C# 允许您使用关键字 abstract 创建抽象类,用于提供接口的部分类的实现。当一个派生类继承自该抽象类时,实现即完成。抽象类包含抽象方法,抽象方法可被派生类实现。派生类具有更专业的功能。
请注意,下面是有关抽象类的一些规则:
您不能创建一个抽象类的示例。
您不能在一个抽象类外部声明一个抽象方法。
通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。
下面的程序演示了一个抽象类:
using System; namespace PolymorphismApplication } abstract class Shape } abstract public int area(); } class Rectangle: Shape } private int length; private int width; public Rectangle( int a=0, int b=0) } length = a; width = b; } public override int area() } Console.WriteLine("مساحة فئة Rectangle:"); return (width * length); } } class RectangleTester } static void Main(string[] args) } Rectangle r = new Rectangle(10, 7); double a = r.area(); Console.WriteLine("面积: {0}",a); Console.ReadKey(); } } }
عندما يتم تجميع وكتابة وتنفيذ الكود أعلاه، سيظهر النتيجة التالية:
مساحة صنف Rectangle: 面积: 70
当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。
虚方法是使用关键字 virtual 声明的。
虚方法可以在不同的继承类中有不同的实现。
对虚方法的调用是在运行时发生的。
动态多态性是通过 抽象类 和 虚方法 实现的。
以下示例创建了 Shape 基类,并创建派生类 Circle、 Rectangle、Triangle, Shape 类提供一个名为 Draw 的虚拟方法,在每个派生类中重写该方法以绘制该类的指定形状。
using System; using System.Collections.Generic; public class Shape } public int X { get; private set; } public int Y { get; private set; } public int Height { get; set; } public int Width { get; set; } // 虚方法 public virtual void Draw() } Console.WriteLine("执行基类的画图任务"); } } class Circle : Shape } public override void Draw() } Console.WriteLine("画一个圆形"); base.Draw(); } } class Rectangle : Shape } public override void Draw() } Console.WriteLine("画一个长方形"); base.Draw(); } } class Triangle : Shape } public override void Draw() } Console.WriteLine("画一个三角形"); base.Draw(); } } class Program } static void Main(string[] args) } // 创建一个 List<Shape> 对象,并向该对象添加 Circle、Triangle 和 Rectangle var shapes = new List<Shape> } new Rectangle() new Triangle(), new Circle(), }; // يستخدم دائرة التكرار لجولات على قائمة الفرعيات، ويتم استدعاء طريقة Draw لكل Shape foreach (var shape in shapes) } shape.Draw(); } Console.WriteLine("اضغط على أي مفتاح للخروج."); Console.ReadKey(); } }
عندما يتم تجميع وكتابة وتنفيذ الكود أعلاه، سيظهر النتيجة التالية:
رسم مستطيل إجراء مهمة الرسم للفئة الأساسية رسم مثلث إجراء مهمة الرسم للفئة الأساسية رسم دائرة إجراء مهمة الرسم للفئة الأساسية اضغط على أي مفتاح للخروج.
برنامج التالي يعرض كيفية حساب مساحة صورة مختلفة باستخدام طريقة虚ية area():
using System; namespace PolymorphismApplication } class Shape } protected int width, height; public Shape(int a = 0, int b = 0) } width = a; height = b; } public virtual int area() } Console.WriteLine("مساحة الفئة الأب:"); return 0; } } class Rectangle: Shape } public Rectangle(int a = 0, int b = 0): base(a, b) } } public override int area() } Console.WriteLine("مساحة فئة Rectangle:"); return (width * height); } } class Triangle: Shape } public Triangle(int a = 0, int b = 0): base(a, b) } } public override int area() } Console.WriteLine("مساحة فئة Triangle:"); return (width * height / 2); } } class Caller } public void CallArea(Shape sh) } int a; a = sh.area(); Console.WriteLine("المساحة: {0}", a); } } class Tester } static void Main(string[] args) } Caller c = new Caller(); Rectangle r = new Rectangle(10, 7); Triangle t = new Triangle(10, 5); c.CallArea(r); c.CallArea(t); Console.ReadKey(); } } }
عندما يتم تجميع وكتابة وتنفيذ الكود أعلاه، سيظهر النتيجة التالية:
مساحة صنف Rectangle: المساحة: 70 مساحة صنف Triangle: المساحة: 25