Ambiguous method calls in case of inheritance

P

Peter Meier

I have a simple problem. I have a class A and a class B which extends
class A. Both classes have a protected method (e.g. 'print') with the
same signature (so B's method override A's method). If I have an
instance of class B which calls some public method of class A in which
the 'print' method is called then the JVM automatically calls B's
'print' method. How can I achieve that A's 'print' method is called? I
already tried it with the following:
'this.print();' or '((A)this).print();' but neither works. I never see
the print out 'Base class'. Could anyone help me (see code snippet
below). Thanks!

Peter


public class A {
public A() {
}

protected void print() {
System.out.println("Base class");
}

public void doSomething() {
print();
}

public static void main(String[] args) {
B b = new B();
b.doSomething();
}
}

class B extends A {
public B() {
}

protected void print() {
System.out.println("Sub class");
}
}
 
R

Roedy Green

How can I achieve that A's 'print' method is called? I
already tried it with the following:

you could do it like this by adding a method in to B to give access to
A's print.

void oldPrint()
{
super.print();
}
 
B

Bjorn Abelli

...
I have a simple problem.

I don't see it as that "simple"... ;-)
I have a class A and a class B which extends
class A. Both classes have a protected method
(e.g. 'print') with the same signature (so B's
method override A's method).

Here you've got some decisions to make.

Do you *want* it to be "overridable" at all?

As you seem to want this particular method to be invoked when doing
something, you might want to make it "final"...

public class A {
...
final void print() {
System.out.println("Base class");
}
...
}

This way you prevent it from being overridden, and if you want a "similar"
method in a subclass, you're forced to name it differently.

class B extends A {
...
protected void printB() {
System.out.println("Sub class");
}
}

Another option is to *hide* it from the subclasses, by simply making it
private.


public class A {
...
private void print() {
System.out.println("Base class");
}
...
}

In this case, the call will be on "the level of A", and doSomething will
invoke A.print, even if you have a print-method in the subclasses, until you
decide to override doSomething! ;-)
How can I achieve that A's 'print' method is called?
I already tried it with the following:
'this.print();' or '((A)this).print();'
but neither works. I never see
the print out 'Base class'.

You need to define for yourself *why* you need this behaviour, and then you
possibly can see whether it fits into one of the categories i sketched
above.

// Bjorn A
 
H

HalcyonWild

Peter said:
I have a simple problem. I have a class A and a class B which extends
class A. Both classes have a protected method (e.g. 'print') with the
same signature (so B's method override A's method). If I have an
instance of class B which calls some public method of class A in which
the 'print' method is called then the JVM automatically calls B's
'print' method. How can I achieve that A's 'print' method is called? I
already tried it with the following:
'this.print();' or '((A)this).print();' but neither works. I never see
the print out 'Base class'. Could anyone help me (see code snippet
below). Thanks!

Peter


public class A {
public A() {
}

protected void print() {
System.out.println("Base class");
}

public void doSomething() {
print();
}

public static void main(String[] args) {
B b = new B();
b.doSomething();
}
}

class B extends A {
public B() {
}

protected void print() {
System.out.println("Sub class");
}
}



If you can program the situation in which A.print() should be called,
do that.

print() //class B
{
if (some condition is true) { super.print(); }
else print();
}

If not, and still want control on which print to call, have another
method in B to call A.print(), something like

otherprint() // or overload(not override) as print(int k)
{
super.print();
}

But frankly, I do not understand the need for doing all this. What is
the problem for which you want to use both print methods.
 
C

charles_n_may

From a modeling perspective, should B really be a specialized type of
A? Consider whether B and A could be sibling classes with an abstract
parent class, P. Implement P.print() and A.print(), but let B inherit
print() from P.
 
A

Andrew McDonagh

Peter said:
I have a simple problem. I have a class A and a class B which extends
class A. Both classes have a protected method (e.g. 'print') with the
same signature (so B's method override A's method). If I have an
instance of class B which calls some public method of class A in which
the 'print' method is called then the JVM automatically calls B's
'print' method. How can I achieve that A's 'print' method is called? I
already tried it with the following:
'this.print();' or '((A)this).print();' but neither works. I never see
the print out 'Base class'. Could anyone help me (see code snippet
below). Thanks!

Peter


public class A {
public A() {
}

protected void print() {
System.out.println("Base class");
}

public void doSomething() {
print();
}

public static void main(String[] args) {
B b = new B();
b.doSomething();
}
}

class B extends A {
public B() {
}

protected void print() {
System.out.println("Sub class");
}
}


If you need the 'print' method to have the same name and parameters list
(even an empty one as above), then you can't have a different
implementation in B and expect the A.print() to be used.

All over ridden methods in Java are Virtual - (i.e polymorphic).

However, as Charles says, your issue is how you are modeling the
relationship between A & B.

You can do as Charles recommends:

public abstract class Printer {
public void print();
}


public class A extends Printer {

public void print() {
System.out.println("A class called");
}

public void doSomething() {
print();
}

public static void main(String[] args) {

Printer printer = null;

// Just showing how we can reassign the ref to point to
// the different subclasses of Printer

printer = new A();
a.doSomething();

printer = new B();
b.doSomething();
}
}

class B extends Printer {
public B() {
}

public void print() {
System.out.println("B class called");
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top