>  기사  >  백엔드 개발  >  C# 다형성

C# 다형성

黄舟
黄舟원래의
2017-02-16 11:12:431595검색


Reprinted from: 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. 각 특정 Shape 클래스가 공통 클래스에서 파생되는 클래스 계층 구조를 만듭니다. 기본 클래스.

  2. 가상 메서드를 사용하면 기본 클래스 메서드에 대한 단일 호출로 모든 파생 클래스에서 해당 메서드를 호출할 수 있습니다.

Shape 클래스와 Override에서 Draw라는 가상 메서드를 제공합니다. 각 파생 클래스에서 이 메서드를 사용하면 해당 클래스가 나타내는 특정 모양을 그릴 수 있습니다. List 개체를 만들고 여기에 원, 삼각형 및 직사각형을 추가합니다. 그리기 화면을 업데이트하려면 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
 */</shape></shape>

在 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# 다형성 C# 다형성

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

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

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.