C# 没有得到这笔遗产
为什么我不能访问S类方法?为什么我能够在类M中创建同名的方法C# 没有得到这笔遗产,c#,oop,inheritance,C#,Oop,Inheritance,为什么我不能访问S类方法?为什么我能够在类M中创建同名的方法 public class S { public S() { } public int myFunc(int a, int b) { return a + b; } } public class M:S { public M() { } public string myFunc(int a, int b) { r
public class S
{
public S()
{
}
public int myFunc(int a, int b)
{
return a + b;
}
}
public class M:S
{
public M()
{
}
public string myFunc(int a, int b)
{
return (a + b).ToString();
}
}
public class Test
{
public static void Main(string[] args)
{
M mm = new M();
mm.myFunc(1,2); // Why I am not able to access S class myFunc
}
}
因为c#不会根据返回类型重载,只会根据名称和参数重载。因此M重载,S的myFunc变得不可访问。更改名称或参数
如果将其强制转换为S,则会丢失M具有的额外值,因为c#不会基于返回类型而重载,只会基于名称和参数。因此M重载,S的myFunc变得不可访问。更改名称或参数
如果将其强制转换为S,则会丢失M具有的额外值,这称为。您可以通过转换引用来访问S
类方法:
public class Test
{
public static void Main(string[] args)
{
M mm = new M();
string x = mm.myFunc(1,2); // calls M.myFunc
int y = ((S)mm).myFunc(1,2); // calls S.myFunc
S ss = new M();
int z = ss.myFunc(1,2); // calls S.myFunc
}
}
定义派生类成员时应使用;否则,您将收到编译器警告
编辑:请注意,成员隐藏与多态性不同。在成员隐藏中,类成员在编译时根据声明的引用类型进行解析。在我上面的示例中,ss
被声明为S
,即使它实际上被分配了一个类型为M
的实例
要实现多态性,需要在基类成员上指定virtual
修饰符,并在派生类成员上指定override
。因此,对虚拟成员的调用在运行时解析为实例的实际类型。但是,多态性不允许您更改返回类型,因此您不能在示例中使用它。这称为。您可以通过转换引用来访问S
类方法:
public class Test
{
public static void Main(string[] args)
{
M mm = new M();
string x = mm.myFunc(1,2); // calls M.myFunc
int y = ((S)mm).myFunc(1,2); // calls S.myFunc
S ss = new M();
int z = ss.myFunc(1,2); // calls S.myFunc
}
}
定义派生类成员时应使用;否则,您将收到编译器警告
编辑:请注意,成员隐藏与多态性不同。在成员隐藏中,类成员在编译时根据声明的引用类型进行解析。在我上面的示例中,ss
被声明为S
,即使它实际上被分配了一个类型为M
的实例
要实现多态性,需要在基类成员上指定
virtual
修饰符,并在派生类成员上指定override
。因此,对虚拟成员的调用在运行时解析为实例的实际类型。但是,多态性不允许您更改返回类型,因此您不能在示例中使用它。更改返回类型并不会重载该方法(一个类中不能有两个完全相同的方法,具有相同的名称和参数以及不同的返回类型)
原因是显而易见的-如何决定,哪一个将被称为
要重载某些内容,必须有不同的参数。更改返回类型并不会重载方法(不能在一个类中有两个完全相同的方法,具有相同的名称和参数以及不同的返回类型) 原因是显而易见的-如何决定,哪一个将被称为
要重载某些内容,必须有不同的参数。您可以通过base.myFunc(1,2)访问它 您可以通过base.myFunc(1,2)访问它 您需要像这样投射对象:
(S(mm)).myFunc(1, 2); // now you acces the int returns.
为了获得良好的实践效果,如果一个方法的返回值与另一个不同,则它们必须具有不同的名称。您需要像这样强制转换对象:
(S(mm)).myFunc(1, 2); // now you acces the int returns.
为了获得良好的实践效果,如果一个方法的返回值与另一个不同,那么它们必须具有不同的名称。因为
public string myFunc(int a, int b)
是
因为
public string myFunc(int a, int b)
是
好的,除了Groove所说的,在C#中,您需要将基方法声明为“virtual”,并将子类中的方法声明为“override”,以便可以正确地重写它,而不破坏多态性。 阅读这两页,它们将帮助您更好地理解:
除了Groove所说的,在C#中,您需要将基方法声明为“virtual”,子类中的方法声明为“override”,以便正确地重写它,而不破坏多态性。 阅读这两页,它们将帮助您更好地理解:
base在主方法中不可访问base在主方法中不可访问我无法理解这一点。因为首先我要继承S类,所以它的方法应该在类M中可用,如果它可用,那么为什么我能够在类M中创建具有相同名称和参数的方法。当您创建具有相同名称和参数的方法时,它会自动重载它。e、 g S的方法在M中变得不可实现。它隐藏了我无法理解的方法。因为首先我要继承S类,所以它的方法应该在类M中可用,如果它可用,那么为什么我能够在类M中创建具有相同名称和参数的方法。当您创建具有相同名称和参数的方法时,它会自动重载它。e、 g S的方法在M中变得不可访问。它隐藏了该方法为什么忽略来自编译器的警告消息?你认为它只是为了给编译器开发人员一些事情去做吗?为什么你忽略了编译器发出的警告消息?你认为它只是为了让编译器开发者做些什么吗?