66 votes

Pourquoi intérieure peut remplacer finale privée de la méthode?

Je me demandais si elle fait sens pour déclarer une méthode privée comme définitive, et j'ai pensé qu'il ne fait pas de sens. Mais j'ai imaginé il y a une exclusivité de la situation et écrit le code pour le comprendre:

public class Boom {

    private void touchMe() {
        System.out.println("super::I am not overridable!");
    }

    private class Inner extends Boom {

        private void touchMe() {
            super.touchMe();
            System.out.println("sub::You suck! I overrided you!");
        }
    }

    public static void main(String... args) {
        Boom boom = new Boom();
        Boom.Inner inner = boom.new Inner();
        inner.touchMe();
    }
}

Il a compilé et travaillé. "Je devrais faire touchMe() final" je pensais et il l'a fait:

public class Boom {

    private final void touchMe() {
        System.out.println("super::I am not overridable!");
    }

    private class Inner extends Boom {

        private void touchMe() {
            super.touchMe();
            System.out.println("sub::You suck! I overrided you!");
        }
    }

    public static void main(String... args) {
        Boom boom = new Boom();
        Boom.Inner inner = boom.new Inner();
        inner.touchMe();
    }
}

et il fonctionne aussi et me dit

chicout@chicout-linlap:~$ java Boom
super::I am not overridable!
sub::You suck! I overrided you!

pourquoi?

87voto

aioobe Points 158466

Les méthodes privées ne peuvent pas être remplacées (méthodes privées ne sont pas héréditaire!) En fait, il ne fait aucune différence si vous déclarez une méthode privée final ou pas.

Les deux méthodes que vous avez déclaré, Boom.touchMe et Boom.Inner.touchMe sont deux complètement méthodes distinctes qui vient d'arriver à partager le même identifiant. Le fait qu' super.touchMe se réfère à une méthode différente que touchMe, est juste parce qu' Boom.Inner.touchMe ombres Boom.touchMe (et non pas parce qu'il remplace).

Cela peut être démontré dans un certain nombre de façons:

  • Comme vous l'avez découvert vous-même, si vous modifiez les méthodes public, le compilateur va se plaindre parce que vous êtes soudainement essayer de passer outre une méthode finale.

  • Si vous gardez les méthodes privées et ajouter l' @Override d'annotation, le compilateur va se plaindre.

  • Comme alpian, si vous lancez l' Boom.Inner objet à un Boom objet (((Boom) inner).touchMe()) Boom.touchMe est appelé (si en effet, elle a été remplacée, le casting n'a pas d'importance).

Question connexe:

8voto

alpian Points 3002

Je pense que le fait qu'il y a vraiment deux méthodes distinctes, ici, est bien démontré par la modification de vos principaux comme suit:

public static void main(String... args) {
    Boom boom = new Boom();
    Boom.Inner inner = boom.new Inner();
    inner.touchMe();
    System.out.println("And now cast it...");
    ((Boom)(inner)).touchMe();
}

Cette affiche maintenant:

super::I am not overridable!
sub::You suck! I overrided you!
And now cast it...
super::I am not overridable!

Et la raison pour laquelle l'appel à super travaux en Inner est parce que vous êtes à la recherche d'une méthode appelée touchMe dans votre super-classe (Boom) qui, de fait, existe et est visible à l' Inner comme il est dans la même classe.

6voto

DNA Points 16180

Les méthodes privées sont invisibles pour les sous-classes, ou de toute autre classe, de sorte qu'ils peuvent avoir le même nom, mais ne sont pas sur l'équitation, l'un de l'autre.

Essayez d'ajouter le @Override annotation, vous obtiendrez une erreur de compilation.

2voto

Ted Hopp Points 122617

Vous pouvez remplacer la méthode, car il est private de chaque classe.

1voto

JProgrammer Points 837

Vous avez juste a déclaré une autre méthode du même nom. Vous êtes en mesure d'appeler privée des membres de la classe parce que l'intérieur de la classe est elle-même membre de la classe. Espérons que cette modification va l'expliquer dans les détails.

public class Boom {

    private final void touchMe() {
        System.out.println("super [touchMe] ::I am not overridable!");
    }

    public void overrideMe(){
        System.out.println("super [overrideMe]::I am overridable!");
    }

    private class Inner extends Boom {

        private void touchMe() {
            super.touchMe();
            System.out.println("sub [touchMe]::You suck! I overrided you!");
        }

        public void overrideMe(){
            System.out.println("sub [overrideMe] ::I overrided you!");
        }
    }

    public static void main(String... args) {
        Boom boom = new Boom();
        Boom.Inner inner = boom.new Inner();

        inner.touchMe();

        Boom newBoom = inner;
        newBoom.touchMe();
        newBoom.overrideMe();
    }
}



super [touchMe] ::I am not overridable!
sub [touchMe]::You suck! I overrided you!
super [touchMe] ::I am not overridable!
sub [overrideMe] ::I overrided you!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X