How does the compiler pick the right overriden method [duplicate] - java

This question already has answers here:
How does Java call object's function?
(5 answers)
How is dynamic binding implemented in Java?
(2 answers)
Closed 9 years ago.
public class Test
{
public static abstract class Node
{
private Node kid;
public abstract int getN();
public Node(Node kid) { this.kid = kid; }
public final Node copyWithNewChild(Node newKid)
{
return new Node(newKid)
{
public int getN()
{
return Node.this.getN(); //****
}
};
}
}
}
As you can see, I have this base class called Node, with a method getN() to be overriden by sub-classes.
Suppose I have a class called RedNode extending Node and providing a concrete implementation for getN(), and that I also have another class called SquareRedNode extending RedNodeand also providing an implementation for getN().
(And certainly, something else could also extend SquareRedNode (ie., the family tree could grow infinitely))
Now question, how does the compiler figure out which getN() to call when the copyWithNewChild() is executed?
(I'm not asking "what" implementation is being picked, which I can easily figure out by compiling/executing the code. I want to know how it is done.)
Thanks,

The compiler doesn't figure it out, it's a virtual method and it doesn't get resolved until runtime.
The JVM looks at the class of the object it's calling getN on and sees if it implements getN. If it does, it uses it, otherwise it looks at the superclass and sees if it implements it. It proceeds up the class hierarchy this way until it finds an implementation.

Related

Java: Call a base super class method while skipping intermediate inherited super classes [duplicate]

This question already has answers here:
Calling super super class method
(12 answers)
Closed 8 years ago.
Let say I have three classes:
class A
{
public void method()
{ /* Code specific to A */ }
}
class B extends A
{
#Override
public void method()
{
/*Code specific to B*/
super.method();
}
}
class C extends B
{
#Override
public void method()
{ /* I want to use the code specific to A without using B */ }
}
The goal in this case is to use the code from A without using the code from B. I thought there was a way to do it by calling the super method, but this brings in the code from B as well.
Is there a way to do this?
The short answer is no. What you're seeing is that your design is flawed. It indicates that you need too move the code in class A out into a helper class. B and C would then use it via composition. You could try using partials to get the behavior you want. See this link for more details. Partial function application in Java 8
You could instantiate an object of class A in C and call the method method
class C extends B
{
#Override
public void method()
{ /* I want to use the code specific to A without using B */
A test = new A();
test.method();
}
}
Not sure if this is what you meant. Also asumed you forget the method name method in class A.
No there is no way to do it. You can simply create another method in class B that executes the code of A's method, and call that method in subclass C.

Java - Invoke selective super class method possible? [duplicate]

This question already has answers here:
Why is super.super.method(); not allowed in Java?
(22 answers)
Closed 8 years ago.
I am using inherited codes which cannot be modified. It is being overrided many times. I want to invoke a specific overrided method of a super class (not a direct super class).
public class SuperSuperClass
{
...
public doSomething()
{
//Does something that I want
}
}
public class SuperClass extends SuperSuperClass
{
...
public doSomething()
{
//Does something I do not want
super.doSomething();
}
}
public class SubClass extends SuperClass
{
...
public doSomething()
{
SuperSuperClass.doSomething(); // is this possible?
}
}
The SuperClass.doSomething() does something I do not want before itself calling SuperSuperClass.doSomething(). Is there a way I can invoke SuperSuperClass.doSomething() from SubClass?
The answer to your question is "no". In Java there is no way to express that you want to invoke an instance method that was defined in some specific class that is part of your inheritance hierarchy. The language provides no way to express that.

Why is private member of a class accessible in compareTo? [duplicate]

This question already has answers here:
Do objects encapsulate data so that not even other instances of the same class can access the data?
(7 answers)
Closed 8 years ago.
I wrote the following class to fiddle around with Comparable/Serializable interfaces.
package testpro;
public class SerialTest implements Comparable {
private int circleSize = 10;
private int getCircleSize() {
return circleSize;
}
#Override
public int compareTo(Object o) {
SerialTest object = (SerialTest) o;
if(getCircleSize()>object.getCircleSize()){ // I can access object.getCircleSize() here, but it's private.. why?
return 1;
}
else if(getCircleSize()<object.getCircleSize()){// I can access object.getCircleSize() here, but it's private.. why?
return -1;
}
else{
return 0;
}
}
}
I'm passing an Object o to compareTo() method, but getCircleSize() is private. So how is that possible, that I've got an access to this?
I'm pretty sure C++ wouldn't let it go.
Private means accessible from the same class only. And you are in the same class, after casting Object o to SerialTest object.
Private method are accessible within the class itself. Since both methods residing the same class, there no problem of accessing it.
The private modifier specifies that the member can only be accessed in
its own class.
Check here for more details
private are not accessible by other classes. But within the class it is accessible for programming. Such as your code, you can use all the private identifiers or methods within the class while generating a result.
C++ also provides this function. You can easily use private method inside a class or method, to generate a response for a function call. It is simple and is legal!
You access to private member from same class. You override method compareTo() and in it you are accessed to your private member.
You can't do this with private member without accessor from each other class.
You can learn this from this link.

why Java class can extends only one class but implements many interfaces? [duplicate]

This question already has answers here:
Why is Multiple Inheritance not allowed in Java or C#?
(17 answers)
Why is there no multiple inheritance in Java, but implementing multiple interfaces is allowed?
(21 answers)
Closed 9 years ago.
In C++, you can extends many classes, so what's the advantages of this design in Java that a class can only extends one class ?
Since interface is a pure kind of class(abstract class actually), why not limit the number of interfaces implementation just like class extension ?
Being able to extend only one base class is one way of solving the diamond problem. This is a problem which occurs when a class extends two base classes which both implement the same method - how do you know which one to call?
A.java:
public class A {
public int getValue() { return 0; }
}
B.java:
public class B {
public int getValue() { return 1; }
}
C.java:
public class C extends A, B {
public int doStuff() {
return super.getValue(); // Which superclass method is called?
}
}
Since interfaces cannot have implementations, this same problem does not arise. If two interfaces contain methods that have identical signatures, then there is effectively only one method and there still is no conflict.

How do I access the super-super class, in Java? [Mini-example inside] [duplicate]

This question already has answers here:
Why is super.super.method(); not allowed in Java?
(22 answers)
Closed 9 years ago.
In the example below, how can I access, from C, the method method() of the class A?
class A {
public void method() { }
}
class B extends A{
public void method() { }
}
class C extends B{
public void method() { }
void test() {
method(); // C.method()
super.method(); // B.method()
C.super.method(); // B.method()
B.super.method(); // ERROR <- What I want to know
}
}
The error I am getting is
No enclosing instance of the type B is
accessible in scope
Answer: No, this is not possible. Java doesn't allow it. Similar question.
You can't - and very deliberately. It would violate encapsulation. You'd be skipping whatever B.method wants to do - possibly validating arguments (assuming there were any), enforcing invariants etc.
How could you expect B to keep a consistent view of its world if any derived class can just skip whatever behaviour it's defined?
If the behaviour B provides isn't appropriate for C, it shouldn't extend it. Don't try to abuse inheritance like this.
Following code could be a work-around (not nice, but should work):
class A {
public void method() { }
}
class B extends A {
public void method() { }
protected void superMethod() {
super.method();
}
}
class C extends B {
public void method() { }
void test() {
method(); // C.method()
super.method(); // B.method()
superMethod(); // A.method()
}
}
Well, there is no direct way of doing this but you can always try workarounds.
I am not sure of the purpose of accessing method in class A from class C but you can always get hold of that method.
You could either create an instance of class A in class C and if that looks too simple, try using reflection API...
[link text][1]
Extreme Java
You shouldn't.
If you want to access the methods in A, extend from A instead of B.
When B extends A, it assumes that the underlying A-object won't be manipulated in other ways than how it does it itself. Therefore, by directly accessing the methods of A, you could be breaking how B functions.
Imagine, for instance, you have a class that implements a list, MyList. Now, imagine we extend this list with another class called MyCountingList, which overrides the add() and remove() methods to count the elements being added/removed. If you bypass the add() method MyCountingList provides, using the one MyList has instead, you've now broken the counting feature of MyCountingList.
So, in short, just don't.

Categories

Resources