Redian新闻
>
A question about inheritance
avatar
A question about inheritance# Java - 爪哇娇娃
s*n
1
Class A extends B;
Class B extends C;
I can call B's method from A by the keyword "super()", and call C's methods
from B, too.
but how can I call C's methods from A?
Thanks!
avatar
e*g
2
if it's overridden by B, you can't.

【在 s*********n 的大作中提到】
: Class A extends B;
: Class B extends C;
: I can call B's method from A by the keyword "super()", and call C's methods
: from B, too.
: but how can I call C's methods from A?
: Thanks!

avatar
s*n
3
thanks for reply. it was one of my interview question and I could not answer
for sure at that time.
after posting it and asking for help, I suddenly find out a way to do it:
use the reflection api to traverse to C and search for the corresponding
method, if exist, invokes it; otherwise, abandons.
what do you think?

methods

【在 e***g 的大作中提到】
: if it's overridden by B, you can't.
avatar
e*g
4
well, reflection is kind of hack outside language and may break OO,
for example, accessing a private member.
however in this perticular case, even reflective method invocation
respects polymorphism, so you can't invoke C's method implementation on A.
i think this is a trick question. even if you could, you shouldn't,
because of general OO principles. A should respect B and don't run cross it.

【在 s*********n 的大作中提到】
: thanks for reply. it was one of my interview question and I could not answer
: for sure at that time.
: after posting it and asking for help, I suddenly find out a way to do it:
: use the reflection api to traverse to C and search for the corresponding
: method, if exist, invokes it; otherwise, abandons.
: what do you think?
:
: methods

avatar
w*n
5
if you do that, I'd rather redesign the class hierarchy.

【在 s*********n 的大作中提到】
: thanks for reply. it was one of my interview question and I could not answer
: for sure at that time.
: after posting it and asking for help, I suddenly find out a way to do it:
: use the reflection api to traverse to C and search for the corresponding
: method, if exist, invokes it; otherwise, abandons.
: what do you think?
:
: methods

avatar
m*t
6

OMG, this is plain hack, hack, hack!

【在 s*********n 的大作中提到】
: thanks for reply. it was one of my interview question and I could not answer
: for sure at that time.
: after posting it and asking for help, I suddenly find out a way to do it:
: use the reflection api to traverse to C and search for the corresponding
: method, if exist, invokes it; otherwise, abandons.
: what do you think?
:
: methods

avatar
F*n
7
This is still impossible because reflection Method.invoke must use an instance
as parameter, if the type this instance is the derived class, then it still
invokes the method in the drived class.

answer

【在 m******t 的大作中提到】
:
: OMG, this is plain hack, hack, hack!

avatar
F*n
8

I don't know why you say so, I don't think it really break OO. for example,
you cannot accesss a private member using reflection.
answer

【在 e***g 的大作中提到】
: well, reflection is kind of hack outside language and may break OO,
: for example, accessing a private member.
: however in this perticular case, even reflective method invocation
: respects polymorphism, so you can't invoke C's method implementation on A.
: i think this is a trick question. even if you could, you shouldn't,
: because of general OO principles. A should respect B and don't run cross it.

avatar
F*n
9
That's the difference betwee Java and C++. In C++, you can declare a
non-virtual function and always cast back to an base class to call the
correspondent implmentation. However, in Java everything is virtual. This is
why Java is much cleaner than C++.

instance
it:

【在 F****n 的大作中提到】
: This is still impossible because reflection Method.invoke must use an instance
: as parameter, if the type this instance is the derived class, then it still
: invokes the method in the drived class.
:
: answer

avatar
e*g
10
yes you can:) lots of framework depend on this capability,
and Sun opens this door because people need it.
it's under security setting thought, of course.

【在 F****n 的大作中提到】
: That's the difference betwee Java and C++. In C++, you can declare a
: non-virtual function and always cast back to an base class to call the
: correspondent implmentation. However, in Java everything is virtual. This is
: why Java is much cleaner than C++.
:
: instance
: it:

avatar
s*n
11
yes. Even though reflection is dangerous to use, it still cannot solve the
problem.
I think the interviewer's meaning is to invoke C's method from object A
without a C object. I still remembered he asked me how to invoked B's method
from A, I said "using super().xxx", then he continued to ask to invoke C's
method form A. I was lost at that time.
do you guys still have any other ideas? or I should take embug's first reply.

instance
it:

【在 F****n 的大作中提到】
: This is still impossible because reflection Method.invoke must use an instance
: as parameter, if the type this instance is the derived class, then it still
: invokes the method in the drived class.
:
: answer

avatar
m*d
12
should be once the compiler can't find the method in b, it gonna automatically
call b's parent, so still use super to call it.

【在 s*********n 的大作中提到】
: yes. Even though reflection is dangerous to use, it still cannot solve the
: problem.
: I think the interviewer's meaning is to invoke C's method from object A
: without a C object. I still remembered he asked me how to invoked B's method
: from A, I said "using super().xxx", then he continued to ask to invoke C's
: method form A. I was lost at that time.
: do you guys still have any other ideas? or I should take embug's first reply.
:
: instance
: it:

avatar
s*e
13
interviewer may just need answer of xxx() and did not consider overrided
cases himself.

【在 m********d 的大作中提到】
: should be once the compiler can't find the method in b, it gonna automatically
: call b's parent, so still use super to call it.

avatar
m*d
14
make another instance of c?

【在 s******e 的大作中提到】
: interviewer may just need answer of xxx() and did not consider overrided
: cases himself.

avatar
s*e
15
if not overrided, why need instance of c? just call the method directly
in A.

【在 m********d 的大作中提到】
: make another instance of c?
avatar
m*t
16

instance
That's a bummer to me. I don't quite understand why it was designed that way,
though. It would seem more intuitive to me that if I manage to get the Method
object from Class C, and specifically call its invoke() on an object, chances
are I would like exactly that method to be executed instead of following the
inheritance graph.

【在 F****n 的大作中提到】
: This is still impossible because reflection Method.invoke must use an instance
: as parameter, if the type this instance is the derived class, then it still
: invokes the method in the drived class.
:
: answer

avatar
F*n
17
That's a good design I think. The key point is that a Class object only
contains the META DATA of a class (signatures) not real defintions, and the
JVM will look for the implementation in the instance's class definitions using
the method signature.

still
way,
Method
chances

【在 m******t 的大作中提到】
:
: instance
: That's a bummer to me. I don't quite understand why it was designed that way,
: though. It would seem more intuitive to me that if I manage to get the Method
: object from Class C, and specifically call its invoke() on an object, chances
: are I would like exactly that method to be executed instead of following the
: inheritance graph.

avatar
F*n
18
Yeah, you are right, that tricky little setAccessible in Field class. I
learned sth. again.

example,
A.
it.

【在 e***g 的大作中提到】
: yes you can:) lots of framework depend on this capability,
: and Sun opens this door because people need it.
: it's under security setting thought, of course.

avatar
m*t
19

using
Well, when I get the Class object of class C, and further a Method object from
it,
I certainly expect that Method object to represent the meta data of the
version on
C, instead of any other versions, right? Furthermore, when I pass an object
reference to this Method object specifically, it would be intuitive that this
specific version of the method is applied to the object passed in. The way it
works now is like using the Method object just to specify the method name,
which
is actually

【在 F****n 的大作中提到】
: That's a good design I think. The key point is that a Class object only
: contains the META DATA of a class (signatures) not real defintions, and the
: JVM will look for the implementation in the instance's class definitions using
: the method signature.
:
: still
: way,
: Method
: chances

avatar
e*g
20
well, intuitive to a procedural mind, not an OO-mind:)
first of all, the method implementation may not exist in C,
say if C is interface, or abstract.
should they provide an alternative? that this method is concrete,
please invoke its implementation regardless subclass overriding?
they may have technical difficulty of doing this, like limit of
JVM bytecode specification, some runtime semantics consideration.
or they may simply give you the typical java answer: dude, you
don't know what you want,

【在 m******t 的大作中提到】
:
: using
: Well, when I get the Class object of class C, and further a Method object from
: it,
: I certainly expect that Method object to represent the meta data of the
: version on
: C, instead of any other versions, right? Furthermore, when I pass an object
: reference to this Method object specifically, it would be intuitive that this
: specific version of the method is applied to the object passed in. The way it
: works now is like using the Method object just to specify the method name,

avatar
s*n
21
I think this is because every method is virtual in java. The Method object
contains only metadata, the actual method invoked depends on the instance on
which the method is invoked.

still
way,
Method
chances

【在 m******t 的大作中提到】
:
: using
: Well, when I get the Class object of class C, and further a Method object from
: it,
: I certainly expect that Method object to represent the meta data of the
: version on
: C, instead of any other versions, right? Furthermore, when I pass an object
: reference to this Method object specifically, it would be intuitive that this
: specific version of the method is applied to the object passed in. The way it
: works now is like using the Method object just to specify the method name,

avatar
m*t
22

he he, I have always considered myself one of the "OO-minds", which
is the reason for me screaming "hack hack hack!" at the beginning.
But we are discuss a different issue from the OP, which is, again,
undeniably, hack, hack, hack! 8-)
My point is that, from (exactly) the OO point of view, a specific
Method object should represent the specific version of the method,
because this Method object is obtained from one specific Class object,
which is abstractly a specific version of the interface.

【在 e***g 的大作中提到】
: well, intuitive to a procedural mind, not an OO-mind:)
: first of all, the method implementation may not exist in C,
: say if C is interface, or abstract.
: should they provide an alternative? that this method is concrete,
: please invoke its implementation regardless subclass overriding?
: they may have technical difficulty of doing this, like limit of
: JVM bytecode specification, some runtime semantics consideration.
: or they may simply give you the typical java answer: dude, you
: don't know what you want,

avatar
m*t
23

OK, let me just remind you guys once again, that Method object is obtained
from a specific Class object. If it only holds the metadata for the method
interface regardless inheritence, the Method objects I got from class A, B,
and C should logically equal to each other, which is evidently not true.

【在 s*********n 的大作中提到】
: I think this is because every method is virtual in java. The Method object
: contains only metadata, the actual method invoked depends on the instance on
: which the method is invoked.
:
: still
: way,
: Method
: chances

avatar
e*g
24

i guess the most important role of a method is as interface, instead of
chunk of code of implemenation, for java.lang.reflect.Method.
the subclass method contract is 'consistent' with super's, but it doesn't have
to be identitcal. it can differ in declaringClass(duh!), modifiers(less
restrictive), exceptionTypes(less declared exception types), returnType
(covariant return type in 1.5? not sure).
so C's method is not equal to A's method. you can call C's method on
A2 object, but you cannot call

【在 m******t 的大作中提到】
:
: OK, let me just remind you guys once again, that Method object is obtained
: from a specific Class object. If it only holds the metadata for the method
: interface regardless inheritence, the Method objects I got from class A, B,
: and C should logically equal to each other, which is evidently not true.

avatar
m*t
25

I agree with you all the way - until the part after "for ..." 8-)
Again, when you get to a specific Method object, it represents
a specific version.
Exactly, every one of all these differences is a reason why
when I invoke on a specific Method object, I want that specific
version of the method to be invoked.
True, but that should be and can be easily enforced by run-time
checking, instead of preventing all C's methods from being called
on A or A2.

【在 e***g 的大作中提到】
:
: i guess the most important role of a method is as interface, instead of
: chunk of code of implemenation, for java.lang.reflect.Method.
: the subclass method contract is 'consistent' with super's, but it doesn't have
: to be identitcal. it can differ in declaringClass(duh!), modifiers(less
: restrictive), exceptionTypes(less declared exception types), returnType
: (covariant return type in 1.5? not sure).
: so C's method is not equal to A's method. you can call C's method on
: A2 object, but you cannot call

avatar
e*g
26
it represents a specific version, of the contract of the method,
instead of implementation of the method.
if you can call C's method impl f() on A object, inside which another
virtual method g() is invoked, then what? you want C::g() or A::g()?
which one is the intuitive one?
your requirement fundermentally changes the method dispatching semantics
of the langauge, it will cause endless confusion and problems.

【在 m******t 的大作中提到】
:
: I agree with you all the way - until the part after "for ..." 8-)
: Again, when you get to a specific Method object, it represents
: a specific version.
: Exactly, every one of all these differences is a reason why
: when I invoke on a specific Method object, I want that specific
: version of the method to be invoked.
: True, but that should be and can be easily enforced by run-time
: checking, instead of preventing all C's methods from being called
: on A or A2.

avatar
F*n
27
Class objects can also represent interfaces, if they are the exact versions,
what should the results be if we invoke an interface method?

obtained
method
B,
have

【在 m******t 的大作中提到】
:
: I agree with you all the way - until the part after "for ..." 8-)
: Again, when you get to a specific Method object, it represents
: a specific version.
: Exactly, every one of all these differences is a reason why
: when I invoke on a specific Method object, I want that specific
: version of the method to be invoked.
: True, but that should be and can be easily enforced by run-time
: checking, instead of preventing all C's methods from being called
: on A or A2.

avatar
m*t
28

If this were in C++, intuitively it would depend on whether g() is
vitual, so as intuitively, since in Java every method is vitual, A::g()
should always be called.
But you do have a point.
I agree, but firstly we all agree that it usually implies a bad design
to require to invoke a specific Method from a superclass, secondly
even when we assume there is a legitimate reason for us to do that,
the accompanying design must be complicated to begin with.

【在 e***g 的大作中提到】
: it represents a specific version, of the contract of the method,
: instead of implementation of the method.
: if you can call C's method impl f() on A object, inside which another
: virtual method g() is invoked, then what? you want C::g() or A::g()?
: which one is the intuitive one?
: your requirement fundermentally changes the method dispatching semantics
: of the langauge, it will cause endless confusion and problems.

avatar
m*t
29

Mmm, that's a good point.

【在 F****n 的大作中提到】
: Class objects can also represent interfaces, if they are the exact versions,
: what should the results be if we invoke an interface method?
:
: obtained
: method
: B,
: have

avatar
c*a
30

Even no interface involved, It is still not easy to run a specific method
anywhere.
A method has to be invoked by a object, in other word, the method must operate
on a certain object in heap. If C extends B and B extends A. How can you
guarantee that an A method implementation can always run successfully against
a C object?
By the way, one special case that to invoke a A method in C is that if B does
not define (override) the same method. Then a super.anAMethod() in C will get
to the method in

【在 F****n 的大作中提到】
: Class objects can also represent interfaces, if they are the exact versions,
: what should the results be if we invoke an interface method?
:
: obtained
: method
: B,
: have

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。