Doubt over access modifiers and polymorphism

2

I have a very early question about polymorphism / access modifiers in Java.

I would like to find out why a certain phenomenon occurs in my code. Here is an example of classes:

Class Pai :

public class Pai {
    public void metodo1() { //private dá problema
        System.out.println("Metodo 01 Pai");
    };

    public void metodo2() {
        metodo1();
    }
}

Class that inherits the previous class:

public class Filha extends Pai{

    public Filha() {
    }

    public void metodo1() {
        System.out.println("Metodo 01 Filha");
    }   
}

And class Main :

public class Main {
    public static void main(String  args[]) {
        Pai instancia = new Filha();
        instancia.metodo2();

    }
}

The println of Main is " Metodo 01 Filha ". However, when you change the modifier from metodo1() from class Pai to private , the return of main method becomes " Metodo 01 Pai ". I would like to understand why this change occurs.

    
asked by anonymous 09.11.2017 / 19:00

2 answers

2

Overlapping methods allows the subclass to override some of the methods it sees in the superclass.

If the superclass method is public or protected, then the subclass sees it, and declaring a method with the same signature will overlap. When the overlay occurs, when calling the superclass method on an instance of the subclass, the method called will be the one that was overwritten.

However, when the superclass method is private, it is hidden from the subclass, so there is no overlap because the subclass does not see it. Only two methods have the same name but operate with no relation between them. Therefore, if the private superclass method is called, the subclass method is not invoked .

Finally, in the case of package visibility, the overclass subclass writes the superclass method only if it is in the same package.

It is recommended to use the @Override annotation in methods of the subclass that intend to overwrite those of the superclass to avoid cases like this. So if the subclass wants to overwrite a method of the superclass but fails, the result is a compilation error, rather than a confusion that only manifests itself in execution. This also mitigates the problem of the superclass method being renamed or otherwise having its signature altered leaving the subclass method overwritten.

    
09.11.2017 / 19:11
1

Private members of the superclass can not be replaced (or even observed) by the daughter classes. Therefore, the method that happens to be considered is the subclass Filha .

Only members with access modifier protected or public can be inherited and replaced with subclasses.

From documentation :

  

Members of a class that are declared private are not inherited by   subclasses of that class. Only members of a class that are declared   protected or public are inherited by subclasses declared in a package   other than the one in which the class is declared.

As you can see in the Victor response, leave the intent explicit, using the @Override :

public class Pai {
    public void digaOla() {
        System.out.println("Olá");
    }
}

public class Filha extends Pai {
    @Override
    public void digaOla() {
        System.out.println("Oi");
    }
}

This annotation is for both the compiler and who will read your code. I already commented on other answers here on the site. Keep in mind that:

  • Explicit is better than implicit. Make your goals clear to anyone who reads the code. This reader can be a co-worker, a unknown in GitHub and until you in a few months trying understand what is written. Read the PEP 20 , applicable here also.
  • Typos. Imagine you want to override Object.toString() and type tostring() . Without the annotation everything goes well, but with the annotation it would give a compile error because it would not % exists. A worse case would be with Object.tostring() .

In languages such as C #, you must denote the intent by using the hashCode() .

    
09.11.2017 / 19:11