views:

108

answers:

5

Polymorphism allows the programmer either to inherit, override or to overload an instance method of Parent Class.

But, it won't allow to make an instance method of parent class as more restrictive in child class. i.e it wont allow to use same name of parent class instance method, to declare as private in the child class.

Also JVM identifies the parent class version of an instance method, if child class didn't override it.

Similarly why don't JVM identifies the parent class version of an instance method, if the child class makes it more restrictive?

The more restrictive method of parent class in child class can be considered as child class specific method instead of overridden method by compiler.

+16  A: 

This is all done in order to follow the Liskov Substitution Principle.

In order for inheritance in object oriented programming to behave as expected, a child class should be able to be substituted out for a parent class instance and not break a user of the class.

Making a child method more restrictive is basically saying "I don't want this method to be visible". Having the JVM automatically substitute out the parent class implementation in this case would just add a huge amount of confusion - just changing the call behavior might cause very unexpected behavior, even completely within the child class...

Reed Copsey
This answer could use a bit of explanation. But yes, it boils down to this. +1 Edit: Thank you :)
delnan
@delnan: I added some more info...
Reed Copsey
Not for me, for others. I know the Liskov principle very well ;)
delnan
@delnan: Hehehehe... That look better?
Reed Copsey
+2  A: 

The more restrictive method of parent class in child class can be considered as child class specific method

Java authors could've implemented this. And many other things, like infamous multiple inheritance. But it would make language more complex for a very little benefit.

If you need a private version of parent's method, why don't you just give it different name? Since it'll be called from your child class only, there won't be much difference.

Nikita Rybak
your answer as a comment to @Colin Hebert's answer will make his answer complete.
JavaGeek
+2  A: 

Java creators decided that Java should be as simple as possible, your question could cause problems with codes like this :

class A {
    public void methodA(){
    }
}
class B extends A {
    @Override
    private void methodA(){
    }
}
//
public static void main(String... args){
    A a = new B();
    a.methodA(); // Should call the overridden method but as it's private it can't work.
}

You provided a solution for this case, but it as has a flaw :

class A {
    public void methodA(){
    }

    public void methodB(){
        methodA();
    }
}
class B extends A {
    @Override
    protected void methodA(){
    }
}
//
public static void main(String... args){
    A a = new B();
    a.methodB(); // Will methodA from A be called or from B ?
}

There the solution is complicated and against the java philosophy. That's more or less why the current solution is used; more simple even if a specific feature can't be used.

Colin Hebert
A: 

If I understand you correctly, you're saying that I should be able to write:

public class Foo
{
  public int bar()
  {
    return 1;
  }
}
public class Foo2 extends Foo
{
  private int bar()
  {
    return 2;
  }
  public int barBar()
  {
    return bar();
  }
}
public static void main(String[] args())
{
  Foo2 foo2=new Foo2();
  System.out.println(foo2.bar());
  System.out.println(foo2.barBar());
}

Then if I create an instance of type Foo2 and call bar from within the class, it should call Foo2.bar so I should get back 2, but if I call bar from outside the class, it should call Foo.bar so I get back 1.

That is, the output of the above program should be: 1 2

Well, as this is a question about the design of the language, I guess the simple answer is, "Because that's how the designers of Java decided to do it."

The real question is, Why would you want it to behave the way you describe? Do you have an application where this would be useful? It seems to me that it would just be confusing.

Jay
A: 

What you want to do is wrap the "parent" class into another using composition, not inheritance when you want to restrict access.

So you create a new class having the class you want to wrap as member and provide access to what you want by designing your own API. Of course, you cannot use the new class in place ot the old one, but that wouldn't make any sense. If that is not want you want to do, I agree 100% with Reed Copsey's answer (I agree 100% even if that is what you wanted to do).

Eric-Karl