Pourquoi ne pouvons-nous pas définir une classe comme protected
?
Je sais que nous ne pouvons pas, mais pourquoi? Il devrait y avoir une raison spécifique.
Pourquoi ne pouvons-nous pas définir une classe comme protected
?
Je sais que nous ne pouvons pas, mais pourquoi? Il devrait y avoir une raison spécifique.
Réponses:
Parce que ça n'a aucun sens.
Le membre de classe protégé (méthode ou variable) est comme package-private (visibilité par défaut), sauf qu'il est également accessible à partir de sous-classes.
Puisqu'il n'y a pas de concept tel que «sous-paquet» ou «héritage de paquet» en Java, déclarer class protected ou package-private serait la même chose.
Vous pouvez cependant déclarer les classes imbriquées et internes comme protégées ou privées.
open
protected
Comme vous le savez, la valeur par défaut est pour l'accès au niveau du package et protected est pour le niveau du package plus les classes non-package, mais qui étend cette classe (le point à noter ici est que vous ne pouvez étendre la classe que si elle est visible!). Disons-le de cette façon:
Puisqu'il n'y a aucun moyen de restreindre cette classe étant sous-classée par seulement quelques classes (nous ne pouvons pas restreindre l'héritage d'une classe par seulement quelques classes parmi toutes les classes disponibles dans un package / en dehors d'un package), il n'y a pas d'utilisation de spécificateurs d'accès protégés pour les cours de haut niveau. Par conséquent, ce n'est pas autorisé.
public class A
{
protected class B
{
}
}
La réponse de @Nikita Rybak a de bons points mais manque de détails, je ne peux pas simplement avoir l'idée sans réfléchir profondément moi-même, ce qui suit est ce que j'ai pensé et maintenant je devrais comprendre complètement la raison.
Quatre modificateurs d'accès, supposons que le 1er niveau est public et le 4ème niveau est privé (basé sur ce tableau dans l'ordre). La première chose que nous devons savoir est pourquoi la classe ne peut pas être définie comme privée au niveau supérieur.
Donc, si "private class foo" (Un membre privé défini, c'est-à-dire que la classe elle-même est un membre) le permet, quel est l'externe (qui contient le membre)? Portée du fichier? Non, le fichier externe est inutile car même plusieurs classes dans un seul fichier seront compilées dans des fichiers de classe séparés. Donc, l'extérieur est le paquet . Mais le modificateur d'accès par défaut de 3ème niveau signifie déjà "package-private ". Ainsi, le modificateur d'accès privé de 4ème niveau ne sera pas utilisé / autorisé.
Mais la classe privée imbriquée est autorisée car l'externe direct est la classe, pas le package, par exemple :
class PrivateNestedMain {
private static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Et si la "classe protégée foo" le permettait? La caractéristique principale protégée est la sous-classe, donc le (package) externe DEVRAIT (en raison de sa portée, mais c'est toujours facultatif) fournir un style de sous - classe , c'est-à-dire sous-package, ou package A extends package B
, mais nous ne savons rien de tel. Ainsi, protected ne peut pas utiliser le plein potentiel (la portée principale est à l'échelle de la sous-classe) au niveau supérieur dont le package externe est (c'est-à-dire pas de sous-package), mais protected peut utiliser le plein potentiel dans la classe imbriquée dont l'extérieur est la classe ( ie peut être une sous-classe) :
class ProtectedNestedMain {
protected static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Notez que ce qui précède dit "ne peut pas utiliser le plein potentiel" car il ne peut pas atteindre toute la sous-classe simplement parce qu'aucune sous-classe externe, c'est-à-dire que la protection réelle peut être autorisée , c'est juste une question de choix pour éviter de dupliquer le travail du package -privée si externe non sous-classable , voir ci-dessous.
Ma confusion est principalement causée par la célèbre table à https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html :
Si le 1er niveau (public) et le 3ème niveau (forfait privé) sont autorisés, comment diable le 2ème niveau intermédiaire (protégé) n'est-il pas autorisé?
sous-classe de soutien public si facile à induire en erreur. La bonne façon de lire ce tableau est
public prend en charge la sous-classe si la sous-classe externe a une fonction de sous-classe.
La même erreur s'applique à package-private, package-private ne prend pas en charge la sous-classe ( N dans la cellule) ne signifie pas que le concept de sous-classe s'applique à l'extérieur.
Cela signifie que nous devons ignorer la colonne Sous -classe si la fonctionnalité de sous-classe n'est pas disponible en externe:
Comme nous pouvons le voir maintenant, les deux niveaux protégés et privés sont au même niveau maintenant ( YYN ), plus aucune confusion sur la raison pour laquelle le niveau intermédiaire n'est pas autorisé. Dans l'ensemble, Java ne choisit que package-private sur protected pour éviter toute confusion ( c'est juste une question de choix , mais la caractéristique principale protégée est la sous-classe, donc package-private est supérieur), et le résultat , seuls 2 modificateurs d'accès sont autorisés au niveau supérieur:
Au niveau supérieur: public ou package-private (pas de modificateur explicite).
La définition d'un champ protected rend ce champ accessible à l'intérieur du package ainsi qu'à l'extérieur du package via l'héritage uniquement (uniquement à l'intérieur de la classe enfant).
Donc, si nous sommes autorisés à rendre une classe protégée, nous pouvons y accéder très facilement à l'intérieur du package, mais pour accéder à cette classe en dehors du package, nous devons d'abord étendre l'entité dans laquelle cette classe est définie, qui est son package.
Et comme un paquet ne peut pas être étendu (peut être importé), définir une classe protégée le rendra à nouveau privé, ce qui revient à le définir par défaut, ce que nous pouvons déjà faire. Il n'y a donc aucun avantage à définir une classe privée, cela ne fera que rendre les choses ambiguës.
Pour plus d'informations, lisez Pourquoi une classe Java externe ne peut pas être privée ou protégée
Protégé n'est pas similaire au public. Protected a à la fois un accès au niveau du package et est accessible en dehors des packages uniquement par héritage.Si une classe dit A en dehors d'un package INHERIT une classe d'un autre package (avec une méthode protégée en utilisant INHERITANCE), elle peut accéder aux méthodes de cette classe B qui a des méthodes protégées mais les sous-classes dérivées de cette classe, c'est-à-dire que A ne peut pas accéder aux méthodes protégées ...
Exemple:
package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
comportement de «protected» = comportement de «default» + «use it in any subclass in any package».
Quoi qu'il en soit, nous avons un modificateur d'accès par défaut pour la classe, le seul avantage que nous pouvons obtenir du modificateur d'accès protégé est: - en l'utilisant dans n'importe quel package via le sous-classement. Mais pour la sous-classe, la visibilité de la classe «protégée» parente serait privée. Donc, il n'est pas accessible. Fondamentalement, si vous avez une classe de premier niveau protégée, aucune classe externe ne peut y accéder en la sous-classant. Ainsi protégé pour une classe de haut niveau n'a pas de sens.
Protégé : VISIBLE uniquement au niveau du package *.
La classe est définie comme protégée ---> elle ne peut pas être étendue depuis un package extérieur (non visible).
Et s'il ne peut pas être étendu, il est inutile de le garder comme protégé , car il deviendra alors un accès par défaut qui est autorisé.
Il en va de même pour les classes définies privées .
Remarque: les classes imbriquées ou internes peuvent être définies comme protégées ou privées .
* : Explorez le mot-clé protégé , pour cette réponse, je l'ai fait succinct.
La réponse de @ Akash5288 n'avait aucun sens pour moi:
Si toutes les classes sont autorisées à sous-classer, il sera similaire au spécificateur d'accès public.
Puisqu'il n'y a aucun moyen de restreindre cette classe étant sous-classée par seulement quelques classes (nous ne pouvons pas restreindre l'héritage d'une classe par seulement quelques classes parmi toutes les classes disponibles dans un package / en dehors d'un package), il n'y a pas d'utilisation de spécificateurs d'accès protégés pour les cours de haut niveau. Par conséquent, ce n'est pas autorisé.
Vous pouvez alors appliquer la même logique aux méthodes et variables protégées, elles sont également alors "similaires au public". Toutes les classes en dehors d'un package peuvent étendre notre classe publique et utiliser ses méthodes protégées. Pourquoi restreindre les méthodes et les variables aux classes étendues est-il correct, mais restreindre la classe entière n'est pas correct? "Similaire au public" n'est pas "identique au public". Mon interprétation est qu'il est parfaitement bien d'autoriser une classe protégée, car il est bien d'autoriser des méthodes protégées.
La réponse "vous ne pouvez pas étendre une classe que vous ne pouvez pas accéder / voir" est plus logique.
Ce qui a du sens pour cette question est que, JVM est écrit en C (Sun JVM) et C ++ (oracle JVM) donc lors de la compilation, nous allons créer des fichiers .class à partir de notre fichier java et si nous déclarons une classe avec le mot-clé Protected alors il ne sera pas accédé par JVM.
La réponse pour laquelle la classe protégée ne sera pas accessible par JVM est que, puisque les champs protégés sont accessibles dans le même package ou à un package différent par héritage uniquement et que la JVM n'est pas écrite de manière à hériter de la classe will. J'espère que cela répond à cette question :)
De même, une classe de niveau supérieur ne peut pas être privée. Explication comme ci-dessous:
Alors que se passera-t-il si nous définissons une classe private, cette classe ne sera accessible qu'au sein de l'entité dans laquelle elle est définie qui dans notre cas est son package?
Ainsi, définir un accès privé à la classe le rendra accessible dans le même package que le mot-clé par défaut fait déjà pour nous. Par conséquent, il n'y a aucun avantage à définir une classe privée, cela ne fera que rendre les choses ambiguës.
protected signifie que le membre est accessible par n'importe quelle classe du même package et par des sous-classes même si elles sont dans un autre package.
Exemple:
package a;
class parent{
protected void p();
}
package b;
import a.p;
class child extends parent{
//you can access method which is protected in the parent in the child
}
class another extends child {
//here you can not access the protected method
}
si une classe externe est déclarée par protected, je pense que vous voulez que la classe ne soit accessible qu'à partir du même package et de sa sous-classe mais avec des packages différents. Cependant, il n'est pas possible de créer des sous-classes pour une classe protégée, car lorsque vous écrivez "classe Chien étend Animal", en raison de "Animal" protégé ne peut être accédé que par sa sous-classe, évidemment, "Chien" n'est pas une sous-classe "Animal" .
La classe externe protégée est donc la même que la classe externe (par défaut)!