-2

This question is raised with a clarification required to decide when to declare a method protected or public during class design of a package.

My point is, if one needs to override a method of a SuperClass then make that method access level as package private or protected in SuperClass but do not give access level public, and then SubClass inherit SuperClass to override that method.

if public access level method is also overridden in SubClass then public access level method has also become an implementation dependent method in every new SubClass designed, which breaks concept of abstraction. Because user using public level access method addNotify(), should know that it's implementation is different in awt.Component/ awt.Checkbox/awt.Button class, which means hiding of implementation details not ensured here. In addition, abstract class is supposed to be discovered and designed to have only common implementations of its concrete subclass methods, But it is pretty strange to see that abstract class Component{} breaks this definition.

With the access level given to this method public void addNotify() {}, Without knowing the meaning or significance of this method, I would like to ask,

Does it become difficult to decide the access level of a method during class design to be either public or protected?

Because I would like to say that at design time any method will be public in SuperClass only when below 2 reasons are satisfied:

1) There must not be a need to override this method in SubClass in/out of package, if one tries to override SuperClass.

2) Based on the signature of any public level method it must be safe after making a decision that this method can be publicly available so that means this method should not be implementation dependent in any new SubClass in/out of package. signature in the sense that, i made my below DList class available to perform sequential update of DList in O(n) time, so no SubClass must override prevNode() method of DList class. This is risky!!! Because prev/next pointers can be manipulated here with bad coding. LSK principle will become safe.

   package DList;/* DList.java */ 
   public class DList {
    ......
      public DListNode prevNode(DListNode node) { /* check this signature*/
        if(node.prev != this.sentinel){
            return node.prev;
        }else{
            return null;
        }
      }
    .......
    }
    /* DListNode.java */
    package List;
    public class DListNode {
       public Object item; /* check this */
       protected DListNode prev;
       protected DListNode next;

      DListNode(Object i, DListNode p, DListNode n) {/* check this signature*/
        this.item = i;
        this.prev = p;
        this.next = n;
      }
    }

So,

With the experience of java code written, it looks easy for me to decide the one of the two possible access levels of all the classes/interface design within a package.

it looks easy to decide while introducing signature of new methods, whether a method should have access level private whether a method should have access level package private

If i understand the below question, It would become easy to decide when a method be protected or public. 1) Why java allows to override public access level methods? Because it is difficult for me to decide when to make my method protected, despite i know that public is more visible than protected among packages. One has to foresee the cost/consequence of introducing a new inheritance relation before giving protected access level to the method of your current design of class.

2) Can i know the proper resource to learn when a method can be protected?

Note: I am a Java beginner who currently understands abstraction/encapsulation/inheritance/polymorphism and about to learn "package and access specifiers"

  • 6
    I don't think you understand encapsulation as it applies to inheritance as well as you think you do. May I suggest you do some reading about the Liskov substitution principle? – Jules Dec 13 '14 at 10:50
  • @Jules i think, LSP is well said in the below answer. Do you still suggest me to read LSP? am sorry am not good at English: "I don't think ...as well as you think you do." Are you saying that, am suppose to first learn what an encapsulation is before asking this query? – overexchange Dec 13 '14 at 23:40
2

The answer to your last question is that it will come to you with experience. But basically, you don't start by adding new methods and then wondering which keyword to use. You start by thinking about what responsibilities the class will have, what promises it will make to the classes around it. Each class handles certain details so that other classes don't have to worry about them, and you can think of it like a bunch of contracts. The access modifiers are the tools you use to state (and to some extent enforce) those contracts.

The answer to your other question is that public, protected, and private are about accessibility, not override-ability. The Java keyword that controls whether something can be overridden in a subclass is final. So if you want a member to be accessible but not overridable, declare it public final. There is no way to do the opposite (overridable in a subclass but not accessible from a subclass) because it doesn't make sense to override something you can't see.

  • so that means, even a protected method in current class will be final if the author feels that this method should not be overridden any more in future. am i correct? Generally books/articles do not answer the way you had, in second para. Infact i said the same in my above comments about final, it is my mistake that i read this answer now because of less votes ): Sorry about that!!! – overexchange Dec 14 '14 at 12:10
  • I suppose you could declare something protected final, but it would be odd. You'd be saying you already know all the ways someone might want to extend your class, and nobody will ever have a good reason to override that method. Basically, you'd be encouraging subclasses (why else have protected methods?) and simultaneously discouraging them (by setting arbitrary limits.) – gatkin Dec 14 '14 at 18:03
  • As for the terminology, I've always seen public, protected, and private described as either "accessibility" or "visibility" modifiers. One example is the Java Language Spec. [Update: fixed serious typo.] – gatkin Dec 14 '14 at 18:12
  • @overexchange By the way, I took into account your self-described skill level when writing my answer. I totally agree with Jules and MichelHenrich that you should read up on LSP and the rest of the SOLID principles; but I think you need to learn more of the language and get experience with the class library before you'll be ready to appreciate why those principles make sense. – gatkin Dec 14 '14 at 18:22
  • private field member can be improvised to protected final for field members(atleast), Because some subclass would like to write it's own algo using that member, without calling SuperClass public access method, which looks fine, from maintenance perspective. – overexchange Dec 14 '14 at 20:21
3

if public access level method is also overridden in SubClass then public access level method has also become an implementation dependent method in every new SubClass designed, which breaks Encapsulation. Because user using public level access method addNotify(), should know that it's implementation is different in awt.Component/ awt.Checkbox/awt.Button class, which means hiding of implementation details not ensured here.

The parts in bold should not be true for the majority of cases. In fact, if you must know the subtype of an object before using it, it's a sign that your abstractions are not good enough in hiding implementation details (leaky). This is further expanded by the Liskov Substitution Principle (LSP), which says that you should be able to write your code around the use of a superclass/interface, and have its behavior unchanged if and when any object of a subclass is given to you.

So to answer your questions:

  1. Java allows you to override public methods because there is nothing wrong in doing that at all. Because some people may misuse a tool, doesn't mean the tool is bad. Follow the LSP and try to keep your abstractions closed enough, and you won't need to worry about extending public behavior of an object in the future.

  2. Given that you have already defined all the public methods, and is simply choosing whether to keep the internal methods private or protected, then you could use the following rule: Leave everything private, until the need for subclassing/overriding exists, then turn it into protected. This is a good guideline especially since we cannot foresee the future, and a very considerable amount of time can be wasted on trying to make everything extensible only to find that there were only few cases where it was useful. If you want to read about the best guidelines for allowing future extensibility, you can read materials around applications of Open-Closed Principle (OCP) - beware though, it is one of the hardest SOLID principles to apply, unless you can see the future (or have enough experience to make very reliable guesses).

Overall, I recommend that you read up on the SOLID principles, with especial focus on LSP and OCP, because they fit with your current problems. Also, I'd recommend reading about Composition vs. Inheritance, since sometimes its better not to extend classes at all, but to compose them of other exchangeable objects instead.

  • wrt point, "you should ... sprclass/interface,..its behavior..a subclass.."- For a product owner owning 5000 files and already running in a production environment, How can he make sure that dev+code_reviewer are following LSP? I mean, are we talking about same C/C++ prod maintenance issues. IN CONTRAST, It is more safe, if one has introduced a bug in overriding a protected method, because there are no users who are using this method directly. For me, It is more important that java should avoid the dev to break LSP instead of product owner ensures LSP .So, the above query. – overexchange Dec 13 '14 at 22:10
  • As per my above comment, i would prefer introducing public final for every public method in SuperClass and design my class accordingly. OK. But it does not make sense to me, if you say, there is nothing wrong in "Java allows you to override public methods because there is nothing wrong in doing that at all." – overexchange Dec 13 '14 at 22:31
  • 1
    Looks like this "product owner" would benefit from employing real professionals instead of trying to defend the code base from amateurs who don't follow simple principles of good software design. :) – MichelHenrich Dec 13 '14 at 22:32
  • 1
    Besides, even if you could only override protected methods, you could still break LSP, after all, private/protected methods are going to be used by the public ones. – MichelHenrich Dec 13 '14 at 22:34
  • With my 10 years of product support experience, I would say, Not every business require a real professional like MichelHenrich. Real professional are also appreciated, after they address the actual question mentioned here. Incidentally i just read this point in the article which also discuss similar point: You make class CoffeeCup public so that clie.. as final, or by declaring the entire CoffeeCup class final. – overexchange Dec 13 '14 at 22:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.