Private methods can't be overridden?

  • Thread starter Johannes Schaub (litb)
  • Start date
J

Johannes Schaub (litb)

I heard today that in Java you cannot override private methods. I'm
wondering about this snippet:

class Printer {
public void print() {
preparePrint();
doPrint();
finalizePrint();
}

private abstract void doPrint();
};

class LaserPrinter extends Printer {
private void doPrint() {
// print stuff
}
};

I wonder why i can't write it like this. Users of "Printer" and derived
classes of Printer are not supposed to call "doPrint" directly, so i would
like to make it private.

I heard from people that do C++ that it is a good idea to make virtual
methods private and public functions non-virtual (non-virtual-interface).

What is the reason Java doesn't follow this path? Thanks in advance for all
answers!
 
L

Lew

Johannes said:
I heard today that in Java you cannot override private methods. I'm
wondering about this snippet:

class Printer {
public void print() {
preparePrint();
doPrint();
finalizePrint();
}

private abstract void doPrint();

This is an illegal statement. Did you try to compile it?

Since a 'private' member cannot be inherited, and an 'abstract' method by
definition must be inherited, the combination 'private abstract' is illegal.

You should read the Java tutorial on java.sun.com and other introductory texts.
<http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html>
<http://java.sun.com/docs/books/tutorial/java/IandI/subclasses.html>
};

class LaserPrinter extends Printer {
private void doPrint() {

Since 'private' methods are not inherited, this is a completely separate
method from the superclass's (illegal as written) 'private' method of the same
signature.

Because 'private' methods are not inherited, the superclass 'print()' method
will call only the superclass 'doPrint()' and will not polymorphically invoke
that of the subclass.
// print stuff
}
};

I wonder why i [sic] can't write it like this.

Because the purpose of 'private' is to prevent just that.
Users of "Printer" and derived classes of Printer are
not supposed to call "doPrint" directly, so i [sic] would
like to make it private.

You cannot make it 'private' and also have it inherit. You can make
'doPrint()' either 'protected' (making it visible to all subclass
implementations whether or not in the same package) or package-private
(default) visibility, making it visible to all implementations in the same
package.
I heard from people that do C++ that it is a good idea to make virtual
methods private and public functions non-virtual (non-virtual-interface).

Java is not C++.
What is the reason Java doesn't follow this path?

Because Java is its own language with its own rules. It isn't C++, it isn't
BASIC, and it isn't FORTRAN.
 
J

Johannes Schaub (litb)

Lew said:
This is an illegal statement. Did you try to compile it?

I'm sorry. My whole question is about why it *doesn't* compile. I feel like
you rushed over my question, call me a "troll" and go on giving me tutorials
that do not seem to answer my question and slapping me for mentioning C++.
Since a 'private' member cannot be inherited, and an 'abstract' method by
definition must be inherited, the combination 'private abstract' is
illegal.

I was told so, which motivated this question.
Since 'private' methods are not inherited, this is a completely separate
method from the superclass's (illegal as written) 'private' method of the
same signature.

Because 'private' methods are not inherited, the superclass 'print()'
method will call only the superclass 'doPrint()' and will not
polymorphically invoke that of the subclass.

I'm aware of that. But i'm wondering for the reason?
// print stuff
}
};

I wonder why i [sic] can't write it like this.

Because the purpose of 'private' is to prevent just that.

Why should it prevent that? It seems like a good thing to have only a method
that can be implemented, and that is not exposed for calls at the same time.
Because Java is its own language with its own rules. It isn't C++, it
isn't BASIC, and it isn't FORTRAN.

That's not a good answer, i'm sorry.
 
M

Mike Schilling

Johannes said:
I heard from people that do C++ that it is a good idea to make virtual
methods private and public functions non-virtual
(non-virtual-interface).

It's a convention used to enforce programming-by-contract. The base class
looks more or less like [1]

private abstract virtual void doFoo();

public final nonvirtual void foo()
{
// enforce preconditions ...

doFoo();

// enforce postconditions
}

Since foo() itself can't be overridden, the precondition and
postcondition-checking code can't be removed or changed. Also, since
doFoo() is private, it can't be called except from foo(), so you can't avoid
the precondition and postcondition-checking code via some backdoor.
What is the reason Java doesn't follow this path?

Becasue Java's a different language that does things differently. You can
make foo effectively non-virtual by declaring it final,. and make doFoo()
difficult to call via a backdoor by making it protected.

1. I'm aware this is a bastardization of Java and C++ syntax. Sue me.
 
R

Roedy Green

What is the reason Java doesn't follow this path? Thanks in advance for all
answers!

In Java, "private" means nobody else should use or override this
method. Even if somebody accidentally reuses the name that protection
should still hold.

If you want some other sort of behaviour, use public, protected or
default.

see http://mindprod.com/jgloss/scope.html
and following links.
--
Roedy Green Canadian Mind Products
http://mindprod.com

When a newbie asks for help tracking a bug in a code snippet, the problem is usually is the code he did not post, hence the value of an SSCCE.
see http://mindprod.com/jgloss/sscce.html
 
E

Eric Sosman

I heard today that in Java you cannot override private methods. [...]

Right. Something that is `private' to a class is *not*
part of the class' API. It's not even visible to other classes,
the idea being that there is no way another class can possibly
depend on it. A consequence: If it's `private', you can change
it or even delete it, and no other class will be affected at all.

If a subclass could inherit (and possibly override) a `private'
method, the method would no longer be private in any meaningful
sense. The superclass would not be free to change the method's
signature -- adding a `throws', for example -- without that change
propagating to the subclasses. The method *would* therefore be
part of the superclass' API, exactly the opposite of what `private'
means.
 
J

Johannes Schaub (litb)

Eric said:
I heard today that in Java you cannot override private methods. [...]

Right. Something that is `private' to a class is *not*
part of the class' API. It's not even visible to other classes,
the idea being that there is no way another class can possibly
depend on it. A consequence: If it's `private', you can change
it or even delete it, and no other class will be affected at all.

If a subclass could inherit (and possibly override) a `private'
method, the method would no longer be private in any meaningful
sense. The superclass would not be free to change the method's
signature -- adding a `throws', for example -- without that change
propagating to the subclasses. The method *would* therefore be
part of the superclass' API, exactly the opposite of what `private'
means.

Oh, i see now. I think this makes sense. Thanks for the nice explanation!
 
L

Lew

I'm sorry. My whole question is about why it *doesn't* compile. I feel like
you rushed over my question, call me a "troll" and go on giving me tutorials
that do not seem to answer my question and slapping me for mentioning C++.

Huh? I never called you anything, much less a "troll". I gave objective
answers to your questions as asked, and asked for objective information
relevant to your stated problem. I am so sorry you didn't find my answers
useful. Do bear in mind that they were accurate and comprehensive.

FWIW, one of the defining characteristics of a troll (which I am most
definitely not calling you) is to take as an insult an answer which is
objective and literally relevant to the question.
I was told so, which motivated this question.
I'm aware of that. But i'm [sic] wondering for the reason?

One can only speculate. However, the observed utility is that 'private'
members are exactly that, members that are owned only by the defining class,
not neighbors in the same package, not children, and not foreign classes.
Since there are four access levels in Java, one of the other three will
certainly do what you are trying to do. So leave 'private' for those things
that really must be, well, private.
// print stuff
}
};

I wonder why i [sic] can't write it like this.
Because the purpose of 'private' is to prevent just that.
Why should it prevent that?

Because if it didn't, the member would be exposed, not private.
It seems like a good thing to have only a method
that can be implemented, and that is not exposed for calls at the same time.

For that you have 'protected' and package-private.
That's not a good answer, i'm [sic] sorry.

I'm sorry, too, because it is the answer, whether you like it or not.
 
R

Roedy Green

I'm sorry. My whole question is about why it *doesn't* compile. I feel like
you rushed over my question, call me a "troll" and go on giving me tutorials
that do not seem to answer my question and slapping me for mentioning C++.

Don't take it personally. Lew does that to everyone. The thinks
everyone is as smart and energetic as he.
Think of him as like House.
--
Roedy Green Canadian Mind Products
http://mindprod.com

When a newbie asks for help tracking a bug in a code snippet, the problem is usually is the code he did not post, hence the value of an SSCCE.
see http://mindprod.com/jgloss/sscce.html
 
J

Joshua Cranmer

I heard today that in Java you cannot override private methods. I'm
wondering about this snippet:

What is the reason Java doesn't follow this path?

Private methods are essentially the only non-virtual, non-static methods
in Java [1]. The developers decided to make private members truly
private--their existence outside the class can only be deduced via a
combination of reflection and telling the environment to screw access
checks.

Private, then, in Java, becomes a way to not add to any API a class
exports, be it for public consumption or for implementation details. The
former of course uses public; the latter uses a combination of protected
and package-protected (default).

[1] Yes, there are final methods, but those are still called via a
virtual method dispatch; the compiler and runtime just bitch at you for
not attempting to override such a method.
 
L

Lew

Johannes Schaub (litb) wrote, quoted or indirectly quoted someone who said :
Roedy said:
Don't take it personally. Lew does that to everyone. The thinks
everyone is as smart and energetic as he.
Think of him as like House.

Sigh. Thanks for the backhanded defense, Roedy. What else might you have
said about my post?

Let's see, I answered the OP's question directly. I gave links that explained
the basics of the relevant Java concepts. I pointed out alternatives that
would accomplish the OP's stated goals. I made statements that were
equivalent to what the other respondents said, e.g., that Java has its own
rules and that C++ concepts don't apply. I never called the OP any names, not
"troll" or anything else. Everything I said was directly relevant, answered
the OP's question completely, and gave him a road to move forward.

Now, isn't that what we're supposed to do?
 
E

EJP

I heard today that in Java you cannot override private methods.
Correct.

I wonder why i can't write it like this.

Because you can't override private methods.
I heard from people that do C++ that it is a good idea to make virtual
methods private

That can't be right, otherwise nobody could call them.
What is the reason Java doesn't follow this path?

I don't think anybody follows it.
 
J

Jukka Lahtinen

Johannes Schaub (litb) said:
Eric said:
On 2/18/2010 2:43 PM, Johannes Schaub (litb) wrote:
I heard today that in Java you cannot override private methods. [...]
Right. Something that is `private' to a class is *not*
part of the class' API. It's not even visible to other classes,
Oh, i see now. I think this makes sense. Thanks for the nice explanation!

If you want to be able to override a method or call it from subclasses,
make it protected instead of private. That way it will still remain
invisible for any class that does not extend the class where you
declared it protected.
 
A

Andreas Leitgeb

Roedy Green said:
In Java, "private" means nobody else should use or override this
method.

Marginally connected ramblings:

If class "Foo" with a private method foo() is actually statically nested
in another class Test, then its private method can be called from the
outer class. One could also place another class Bar into Test, that at
first glimpse *appears* to override foo(), but even despite this Bar.foo()
is able to call "itself" per super, it isn't really overriding it!


---snip Test.java---
public class Test {
public static void main(String[] a) {
System.out.println(new Foo().foo()); // -> 42
System.out.println(new Bar().foo()); // -> 54
System.out.println(new Bar().bar()); // -> -42
}

static class Foo {
private int foo() { return 42; }
public int bar() { return -foo(); }
}

static class Bar extends Foo {
// @Override // compile error! (cannot be fooled)
public int foo() {
return super.foo() + 12;
}
}
}
---snip Test.java---
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top