C#中的多态性

2023-10-14 17:03:46 浏览数 (1)

C# 中的多态性 先来看一个例子:

代码语言:javascript复制
class A { } 

class B : A { }

public class Program
{
    public static void Main(string[] args)
    {
        A a = new B(); //No error?!
    }
}

为什么没有抛出错误?当B继承A时,它就变成了A的一种形式,这意味着它可以在需要时作为A传递

再来看:

代码语言:javascript复制
using System;

public class Program
{
    public static void Main(string[] args)
    {
        DoSomething(new A());
        DoSomething(new B());
    }
    static void DoSomething(A obj)
    {
        Console.WriteLine($"Object Type: {obj.GetType()}");
    }
}

打印:

代码语言:javascript复制
Object Type: A
Object Type: B

其它例子:

代码语言:javascript复制
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main(string[] args)
    {
        List<A> objs = new List<A>();
        objs.Add(new A());
        objs.Add(new B());
        foreach (A obj in objs)
        {
            Console.WriteLine($"Object Type: {obj.GetType()}");
        }
    }
}

打印:

代码语言:javascript复制
Object Type: A
Object Type: B

不同于Java。Java中的泛型实现,是采用运行时类型擦除实现的,所以打印List集合看不到具体类型

重写方法

多态性的另一个用法:重写方法

现在可以使用两个关键字来完成方法重写:virtual和override。Virtual本质上是方法/字段以类的形式被重写。Override是对方法/字段的调用

来看看实际应用:

代码语言:javascript复制
using System;

public class Program
{
    public static void Main(string[] args)
    {
        DoStuff(new A());
        DoStuff(new B());
    }
    static void DoStuff(A obj)
    {
        obj.DoSomething();
    }
}

class A
{
    public virtual void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}

打印:

代码语言:javascript复制
I did something in A's method!
I did something in B's method!

这两个对象都作为类型A传递,但对同一方法有不同的实现!

sealed关键字

代码语言:javascript复制
class A
{
    public virtual void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public sealed override void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}

class C : B
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something in C's method!");
    }
}

打印:

代码语言:javascript复制
error CS0239: 'C.DoSomething()': cannot override inherited member 'B.DoSomething()'

我们可以看到,sealed切断了重写方法的调用链

注意:当使用一个类的形式作为基类时,任何new的方法/字段将无法隐藏原来的方法/字段。

示例:

代码语言:javascript复制
using System;

public class Program
{
    public static void Main(string[] args)
    {
        DoStuff(new A());
        DoStuff(new B());
    }
    static void DoStuff(A obj)
    {
        obj.DoSomething();
    }
}

class A
{
    public void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public new void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}

打印:

代码语言:javascript复制
I did something in A's method!
I did something in A's method!

由于将B作为类型a传递,new关键字失败(这就是为什么存在override !) new 的一个例子:

代码语言:javascript复制
using System;

public class Program
{
    public static void Main(string[] args)
    {
        new A().DoSomething();
        new B().DoSomething();
    }
}

class A
{
    public void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public new void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}

打印:

代码语言:javascript复制
I did something in A's method!
I did something in B's method!

关键字base

最后一个关键字是basebase关键字允许从它的形式上访问基类方法和字段,而不必创建一个全新的对象

示例:

代码语言:javascript复制
using System;

public class Program
{
    public static void Main(string[] args)
    {
        new B().DoSomething();
    }
}

class A
{
    public virtual void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
        base.DoSomething();
    }
}

打印:

代码语言:javascript复制
I did something in B's method!
I did something in A's method!

0 人点赞