为什么objA不能访问methodB(),因为它包含对B类对象的引用?
Class A
{
public void methodA()
{
.........
}
}
Class B:A
{
public void methodB()
{
..........
}
}
现在
A obj1= new B();
这会引发错误:
obj1.methodB();
为什么? obj1 包含对 B 类型对象的引用,但仍然无法访问它的成员函数。
答案 0 :(得分:2)
您声明了A
类型的变量:
A obj1
并且A
没有名为methodB
的方法。如果您希望变量的类型为B
,请将其声明为:
B obj1= new B();
(这当然意味着您不能将A
的任何其他实现存储在该变量中,只能B
。)
或者,如果您不想更改变量,则需要转换变量:
(obj1 as B).methodB();
(如果obj1
包含<{1}}的实施,不 <{1}},那么这当然会失败。)
基本上,当您声明类型为A
的变量时,编译器会将其维护为类型B
。在声明之后的任何时候都无法保证变量将包含A
的实例。我可以包含实现A
的任何的实例。
答案 1 :(得分:1)
当你将这两行完美地放在一起时,你会想到#34;当然我可以在那个对象上执行methodB()
!它显然是 一个B
!&#34;。
但现在考虑一下:
private void DoSomethingWithAnA(A obj1)
{
obj1.MethodB();
}
为什么会这样?在此方法中,您只知道收到一个对象A
,没有人会认为您必须使用对象B
来调用它。毕竟,如果您的方法想要使用B
执行某项操作,则应该要求B
,而不是A
!
当然,我可以使用B
调用方法,这不会有问题:
DoSomethingWithAnA(new B());
但这并不意味着DoSomethingWithAnA
突然会对B
做一些事情,它只会对A
做一些事情。
如果你也想做一些特定于B的事情,你可以:
private void DoSomething(A obj1)
{
obj1.MethodA();
if (obj1 is B)
{
((B)obj1).MethodB();
}
}
如果您将B
传递给{{1>},则此方法 会对B
执行某些操作。但是,首先需要检查您发送的A
是否实际上也是B
,然后将<{em} A
投射到B
。在结果B
上,它可以调用MethodB()
。
答案 2 :(得分:0)
因为它被称为从基类到派生的限制性视图。如果您使用polymorphism
实例化对象,就像执行obj1.methodB();
一样,obj1
只拥有父类中定义的内容。这是可能的,因为我们知道派生类也必须具有这些定义(字段,属性,方法等)。
这就是为什么你不能调用显式obj1.methodB();
但你可以用派生类实现调用methodA()
。
示例:
A objA = new A();
objA.methodA(); //calling method implementation of class A
objA.methodB(); //compile time error -> class A doesn't have that method
A objA = new B();
objA.methodA(); //calling method implementation of class B
objA.methodB(); //compile time error -> during restrictive view trough parent class
B objB = new B();
objB.methodA(); //calling method implementation of class B
objB.methodB(); //calling method implementation of class B
想象一下,你有C,D等类,如果用限制性视图实例化它们,你可以为所有这些(子类)调用公共方法(在父类中定义)。
实施例
List<A> list = new List() {objB,objC,objD};
foreach(A obj in list){
obj.MethodA();
}