Prev: Can I install new JavaRuntime version on top of previous? Automatic (CLASS)PATH change?
Next: [ANN] XMLmind MultipartRequest
From: Johannes Schaub (litb) on 18 Feb 2010 14:43 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!
From: Lew on 18 Feb 2010 15:04 Johannes Schaub (litb) wrote: > 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> <http://java.sun.com/docs/books/tutorial/java/IandI/abstract.html> Google for more. > }; > > 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. -- Lew
From: Johannes Schaub (litb) on 18 Feb 2010 15:18 Lew wrote: > Johannes Schaub (litb) wrote: >> 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? > 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. > >> }; >> >> 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. > 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. >> 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. > That's not a good answer, i'm sorry.
From: Mike Schilling on 18 Feb 2010 15:20 Johannes Schaub (litb) wrote: > > 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.
From: Roedy Green on 18 Feb 2010 15:26
On Thu, 18 Feb 2010 20:43:30 +0100, "Johannes Schaub (litb)" <schaub-johannes(a)web.de> wrote, quoted or indirectly quoted someone who said : >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 |