覆盖“公共”继承成员时无法更改访问修饰符

时间:2018-05-17 04:59:36

标签: c# override adapter

我想要adapter模板。
AutoToTravelAdapter Move();方法 我怎样才能overrideinherit传输方式?我尝试使用虚拟但它不起作用。我更改为公共覆盖void两个适配器中的Move(),这是有效的!谢谢, Zohar Peled

using System;

namespace Adapter
{

    class Program
    {
        static void Main(string[] args)
        {
            Traveller traveller = new Traveller();
            Transport camelTransport = new CamelToTravelAdapter();
            Transport autoTransport = new AutoToTravelAdapter();
            traveller.Travel(camelTransport);
            traveller.Travel(autoTransport);
            Console.Read();
        }
    }

     public class Transport
    {
       virtual public   void Move() { Console.WriteLine("trans Moves"); }
    }
    class Auto
    {
        public void Drive()
        {
            Console.WriteLine("Car drive");
        }
    }
    class Traveller
    {
        public void Travel(Transport transport)
        {
            transport.Move();
        }
    }
    class Camel
    {
        public void Move()
        {
            Console.WriteLine("Camel Moves");
        }
    }
    public class CamelToTravelAdapter : Transport
    {
        private Camel camel = new Camel();

          private new void Move()
        {
            camel.Move();
        }
    }

    public  class AutoToTravelAdapter : Transport
    {
        private Auto auto = new Auto();
        **private override  void  Move()**
        {
            auto.Drive();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

标题非常清楚 - 覆盖方法必须与它覆盖的虚拟方法匹配,不仅仅是它的签名(名称和参数),还有它的访问修饰符和返回类型。 为什么?因为(至少)多态和方法重载规则。

多态性是面向对象编程的基本原则,它基本上是能够将派生类视为它的基类。这意味着如果基类具有类似public void move()的方法,则派生类也具有此方法 - 在派生类中继承未更改或覆盖。

方法重载的规则非常简单 - 您可以使用多个具有相同名称但签名不同的方法。该方法的签名是它的名称和它的参数的组合 - 因此不允许仅通过返回类型或访问修饰符而不同的重载。

想象一下如果编译器允许你在继承中更改访问修饰符 - 你最终会得到这样的类:

警告:前面的代码不正确!

public class Transport
{
   public virtual void Move() { Console.WriteLine("trans Moves"); }
}

public class AutoToTravelAdapter : Transport
{
    private Auto auto = new Auto();
    private override void  Move()
    {
        auto.Drive();
    }
}

所以AutoToTravelAdapter实际上会有两个具有相同签名的Move方法 - 一个在AutoToTravelAdapter类中声明的私有,以及一个从{{1}继承的公共}。
显然,这会使Transport类中的Move()方法无法进行调用,因为编译器无法区分这两种方法。