一个简单的继承方法问题
System.out.println(a1.f(b)); //A and A
System.out.println(a1.f(c)); //A and A
System.out.println(a1.f(d)); //A and D
首先他调用的是类A的方法.这应该不用解释了.其次BC丙个对像已经转成了类A的对像.所以输出A and A.
public String f(A obj){return ("B and A");}接受一个类D的对像.当然就输出A and D
下面的应该不用解释了.
一句话.多态!
当然这是个人理解!
俺也是个菜鸟滴!呵
先看自己有没有匹配的,没有再从父类找~
public static void main(String args[]) {
A a1 = new A();
A a2 = new B();//a2是类A的对象,可以调用类B中覆写类A中和类A本身的方法,
//a2是使用上传的方法声明的
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.f(b)); //A and A,A是父类,只能调用A类中的方法
System.out.println(a1.f(c)); //A and A,对象c是类A的孙子C的对象,所以可以向上转型为A的对象
System.out.println(a1.f(d)); //A and D,对象d是D类的对象,所以可以调用类A的f(D obj)方法
System.out.println(a2.f(b)); //B and A,
System.out.println(a2.f(c)); //B and A
System.out.println(a2.f(d)); //A and D,因为类B中没有覆写f(D obj)的方法,所以调用的是类A中的方法
System.out.println(b.f(b)); //B and B,b是类B的对象,所以调用类B的方法f(B obj)
System.out.println(b.f(c)); //B and B,因为c是类B的子类C的对象,而且类B中没有f(C obj)方法,所以调用类B的f(B obj)
System.out.println(b.f(d)); //A and D,因为类B没有f(D obj)的方法,而且d是类A的子类的子类D的对象,所以调用的是类A的方法
}
其中System.out.println(a2.f(b)); //B and A,
System.out.println(a2.f(c)); //B and A
这两句没明白,哪位高手解释一下啊,谢谢
System.out.println(a2.f(b)); //B and A
a2是A对象,但用B初试化的
所以传进去一个B对象,在A的方法里找到
public String f(A obj){return ("A and A");}
因为是被B初试化的,所以方法体要用B里面覆盖的方法
public String f(A obj){return ("B and A");}
所以就得到结果了
楼上仁兄说的对,先在自己的里面找,然后再到父类找,但要注意的是你如果是用子类初试话的话,那方法体就给覆盖了,
System.out.println(a2.f(b)); //B and A,
System.out.println(a2.f(c)); //B and A
这两句一样的,就是上面我说的原因,查找方法是在A里面查找的,但运行的操作是B里面覆盖的,所以是不会出现B and B的,只有//B and A,
有没有高手解释一下对象查找父类和调用其中方法的规则和顺序,比如最后一句
System.out.println(b.f(d)); //A and D
同样,D is a B is a A,但为什么执行的不是B类中的public String f(B obj){return ("B and B");}方法,而是A类中的public String f(D obj){return ("A and D");}方法,是不是方法调用的顺序上的规则所致?
先谢过了。
obj.func(param);
根据引用obj类型和参数param类型来匹配:
1)先在obj引用对应的类中找(A a2 = new B();是在A中找的)有没有参数跟param类型相同的方法,有调用;
2)没有,看有没有参数跟param类型的直接父类相匹配的,有则调用;依次上溯到Object类
3)仍没有匹配的,在引用obj的直接父类的方法中按1)2)的次序仿效匹配参数类型.没有匹配到的话再往上一层父类方法中找,直到上溯到Object类.
4)仍没有匹配的,会报错.
这样可以明白除了第4,5个以外的调用了吧.
这两个例外的情况就是多态(追究概念的话上面属于继承~)
因为a2实际是B类型,而B继承A,A、B中都有f(A obj)方法,它会调用B的f方法而不是A的.
汗一个!
2)3)点说反了~
System.out.println(b.f(d)); //A and D
是因为b对象里面有一个可以直接调用的方法
public String f(D obj){return ("A and D");}
既然能直接调用就不会继续去转化传进来的对象了
如果你把这个方法去掉,那结果就不会是这样了,你可以改一下再试试看
匹配的时候是参数优先的.
有一个典型的例子就是
接口 java.lang.Comparable中的boolean equals(Object obj)方法
不要误写为:
boolean equals(MyClass obj)
这样就不是多态了~
如果是参数优先,那为什么呢?
System.out.println(a2.f(b)); //B and A,
System.out.println(a2.f(c)); //B and A
多态呀
sandflying(飞沙) ( ) 信誉:100 Blog
=========================================
恩,这个我已经明白了,class B 里已经继承了public String f(D obj){return ("A and D");},所以System.out.println(b.f(d)); //A and D可以直接在class B里找到该方法.
比如:
class A
{
public String f(C obj){return ("A and C");}
};
class B extends A
{
};
class C extends B
{
};
class D extends C
{
public String f(B obj){return ("D and B");}
};
class Test
{
public static void main(String[] args)
{
D d=new D();
System.out.println(d.f(d)); //调用的会是A的方法~
}
}
System.out.println(a2.f(b)); //它的结果为什么不是B and B呢?
a2是类B的对象,它覆写了类A的方法,b是类B的对象,所以...
changyuming(常) ( ) 信誉:97 Blog 2006-12-15 13:12:11 得分: 0
System.out.println(a2.f(b)); //它的结果为什么不是B and B呢?
a2是类B的对象,它覆写了类A的方法,b是类B的对象,所以...
=========
因为a2是A类型的呀(虽然它实际上是B的实例)
比如说B中有个方法叫funcB()但A中没有,此时:
A a = new B();
a.funcB();//这么写会报错的!!调用方法它看引用是什么类型
多态,一层一层向上找。
我的理解不知道对不对
class A{ //包含2个方法A.f(D obj)、A.f(A obj)
public String f(D obj){return ("A and D");}
public String f(A obj){return ("A and A");}
}
class B extends A{ //包含3个方法,A.f(D obj)、A|B.f(A obj)(已覆盖)、B.f(B obj)
public String f(B obj){return ("B and B");}
public String f(A obj){return ("B and A");}
}
class C extends B{} //包含3个方法
class D extends B{} //包含3个方法
class test{
A a1 = new A();
//a1有两个方法A.f(D obj)、A.f(A obj)
A a2 = new B();
//a2只有两个方法A.f(D obj)、A|B.f(A obj)(已覆盖),B.f(B obj)对于a2不可见
B b = new B();
//b有三个方A.f(D obj)、A|B.f(A obj)、B.f(B obj)
C c = new C();
D d = new D();
System.out.println(a1.f(b));
//a1没有这种参数形式,调用a1.f((super)b),就是调用a1.f((A)b)---->"A and A"
System.out.println(a1.f(c));
//a1没有这种参数形式,调用a1.f((super)((super)b)),就是调用a1.f((A)b)---->"A and A"
System.out.println(a1.f(d));
//调用a1.f(d)---->"A and D"
System.out.println(a2.f(b));
//由于B.f(B obj)对于a2不可见,a2没有这种参数形式,调用a2.f((super)b),就是调用a2.f((A)b)(已覆盖)---->"B and A"
System.out.println(a2.f(c));
//由于B.f(B obj)对于a2不可见,a2没有这种参数形式,调用a2.f((super)((super)b)),就是调用a2.f((A)b)(已覆盖)---->"B and A"
System.out.println(a2.f(d));
//调用a2.f(d)---->"A and D"
System.out.println(b.f(b));
//调用b.f(b)---->"B and B"
System.out.println(b.f(c));
//b没有这种参数形式,调用b.f((super)c),就是调用b.f((B)c)---->"B and B"
System.out.println(b.f(d));
//调用b.f(d)---->"A and D"
}
看了上面的,明白一点了
#include
using namespace std;
class D;
class A
{
public:
void f(A* a){
cout<<"A and A"<
void f(D* d){
cout<<"A and D"<
};
class B :public A
{
public:
void f(A* a){
cout<<"B and A"<
void f(B* b){
cout<<"B and B"<
};
class C : public B{
};
class D:public B{
};
void main()
{
A *a1 = new A();
A *a2 = new B();
B *b = new B();
C *c = new C();
D *d = new D();
a1->f(b);
a1->f(c);
a1->f(d);
a2->f(b);
a2->f(c);
a2->f(d);
b->f(b);
b->f(c);
b->f(d);
delete a1;
delete a2;
delete b;
delete c;
delete d;
}
我在VC6下执行,结果却是:
A and A
A and A
A and D
A and A
A and A
A and D
B and B
B and B
B and B
各位帮忙解释一下哈
1.把A::f(A* a)声明为virtual.
但是b->f(d) 怎么不调用A::f(D* d)呢?也就是最后那个应该是A and D才对啊。
请教。
我在派生类里重载父类的函数,比如
class A
{
public:
void f(int){
cout<<"A and int"<
};
class B :public A
{
public:
void f(double ){
cout<<"B and double"<
};
然后我这么调用:
B *b = new B();
int i = 5;
b->f(i);
输出却是 B and double? 为什么呢。