覆盖 'public' 继承成员时无法更改访问修饰符 '
Cannot change access modifiers when overriding 'public' inherited member '
我想做adapter
模板。
AutoToTravelAdapter
Move() 有错误;方法
我怎样才能override
和inherit
传输方法?我尝试使用虚拟但它不起作用。我在两个适配器中更改为 public override 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();
}
}
}
标题非常明确 - 重写方法必须与其重写的虚拟方法相匹配,不仅通过它的签名(名称和参数),而且通过它的访问修饰符和 return 类型。
为什么?因为(至少)多态性和方法重载规则。
多态性是 object 面向编程的基本原则,基本上是将派生 class 视为基础 class 的能力。这意味着如果基础 class 有一个像 public void move()
的方法,派生的 class 也有这个方法 - 要么继承不变,要么在派生的 class.[=18 中被覆盖=]
方法重载的规则非常简单——你可以有多个同名但不同签名的方法。该方法的签名是它的名称和参数的组合 - 因此不允许仅 return 类型或访问修饰符不同的重载。
想象一下,如果编译器允许您更改继承中的访问修饰符 - 您最终会得到这样的 class:
警告:前面的代码不正确!
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
class 中声明的私有方法,另一个 [=45] =] 继承自 Transport
.
显然,这将使从 AutoToTravelAdapter
class 内部调用 Move()
方法变得不可能,因为编译器无法区分这两种方法。
我想做adapter
模板。
AutoToTravelAdapter
Move() 有错误;方法
我怎样才能override
和inherit
传输方法?我尝试使用虚拟但它不起作用。我在两个适配器中更改为 public override 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();
}
}
}
标题非常明确 - 重写方法必须与其重写的虚拟方法相匹配,不仅通过它的签名(名称和参数),而且通过它的访问修饰符和 return 类型。
为什么?因为(至少)多态性和方法重载规则。
多态性是 object 面向编程的基本原则,基本上是将派生 class 视为基础 class 的能力。这意味着如果基础 class 有一个像 public void move()
的方法,派生的 class 也有这个方法 - 要么继承不变,要么在派生的 class.[=18 中被覆盖=]
方法重载的规则非常简单——你可以有多个同名但不同签名的方法。该方法的签名是它的名称和参数的组合 - 因此不允许仅 return 类型或访问修饰符不同的重载。
想象一下,如果编译器允许您更改继承中的访问修饰符 - 您最终会得到这样的 class:
警告:前面的代码不正确!
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
class 中声明的私有方法,另一个 [=45] =] 继承自 Transport
.
显然,这将使从 AutoToTravelAdapter
class 内部调用 Move()
方法变得不可能,因为编译器无法区分这两种方法。