Je lisais Guide du programmeur pour Certification Java ™ SCJP de Khalid Mughal.
Dans le chapitre Héritage, il explique que
L'héritage des membres est étroitement lié à leur déclarée accessibilité. Si un membre de la superclasse est accessible par son simple nom dans la sous-classe (sans utiliser de syntaxe supplémentaire comme super), que le membre est considéré comme hérité
Il mentionne également que les méthodes statiques ne sont pas héritées. Mais le code ci-dessous est parfaitement correct:
class A
{
public static void display()
{
System.out.println("Inside static method of superclass");
}
}
class B extends A
{
public void show()
{
// This works - accessing display() by its simple name -
// meaning it is inherited according to the book.
display();
}
}
Comment puis-je utiliser directement display()
en classe B
? Encore plus, B.display()
fonctionne également.
L'explication du livre s'applique-t-elle uniquement aux méthodes d'instance?
Toutes les méthodes accessibles sont héritées par des sous-classes.
À partir de Sun Java Didacticiels :
Une sous-classe hérite de tous les membres publics et protégés de son parent, quel que soit le package dans lequel elle se trouve. Si la sous-classe est dans le même package que son parent, elle hérite également des membres package-private du parent. Vous pouvez utiliser les membres hérités tels quels, les remplacer, les masquer ou les compléter par de nouveaux membres
La seule différence entre les méthodes héritées static (class) et les méthodes héritées non-statiques est que, lorsque vous écrivez une nouvelle méthode statique avec la même signature, l'ancienne méthode statique est simplement masquée et non remplacée.
À partir de page sur la différence entre remplacer et masquer.
La distinction entre cacher et annuler a des implications importantes. La version de la méthode substituée appelée est celle de la sous-classe. La version de la méthode cachée appelée est différente selon qu'elle est appelée depuis la superclasse ou la sous-classe.
Si c'est ce que dit vraiment le livre, c'est faux. [1]
La spécification de langage Java n ° 8.4.8 indique:
8.4.8 Héritage, dérogation et dissimulation
Une classe C hérite de sa superclasse directe toutes les méthodes concrètes m (statiques et instances) de la superclasse pour lesquelles toutes les conditions suivantes sont vraies:
m est un membre de la superclasse directe de C.
m est public, protégé ou déclaré avec l'accès au package dans le même package que C.
Aucune méthode déclarée en C n'a une signature qui est une sous-signature (§8.4.2) de la signature de m.
[1] On ne dit pas ça dans ma copie, 1ère édition, 2000.
Vous pouvez constater la différence entre le code suivant, qui est légèrement modifié par rapport à votre code.
class A {
public static void display() {
System.out.println("Inside static method of superclass");
}
}
class B extends A {
public void show() {
display();
}
public static void display() {
System.out.println("Inside static method of this class");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
b.display();
A a = new B();
a.display();
}
}
Cela est dû aux méthodes statiques sont des méthodes de classe.
A.display () et B.display () appellent la méthode de leurs classes respectives.
B.display () fonctionne parce que la déclaration statique fait que la méthode/le membre appartient à la classe et non à une instance de classe particulière (aussi appelée Object). Vous pouvez en lire plus à ce sujet ici .
Une autre chose à noter est que vous ne pouvez pas écraser une méthode statique, vous pouvez demander à votre sous-classe de déclarer une méthode statique avec la même signature, mais son comportement peut être différent de celui auquel vous vous attendiez. C'est probablement la raison pour laquelle il n'est pas considéré comme hérité. Vous pouvez consulter le scénario problématique et l'explication ici .
Ce concept n’est pas aussi simple qu’il en a l’air. Nous pouvons accéder aux membres statiques sans héritage, ce qui est HasA-relation. Nous pouvons accéder aux membres statiques en développant également la classe parente. Cela n'implique pas qu'il s'agisse d'une relation ISA (héritage). En réalité, les membres statiques appartiennent à la classe et static n'est pas un modificateur d'accès. Tant que les modificateurs d'accès permettent d'accéder aux membres statiques, nous pouvons les utiliser dans d'autres classes. Comme si c'était public, il serait accessible à l'intérieur du même paquet et également à l'extérieur du paquet. Pour les particuliers, nous ne pouvons l'utiliser nulle part. Par défaut, nous ne pouvons l'utiliser que dans le package. Mais pour les protégés, nous devons élargir la classe supérieure. Donc, obtenir la méthode statique dans une autre classe ne dépend pas de son statut statique. Cela dépend des modificateurs d'accès. Donc, à mon avis, les membres statiques peuvent accéder si les modificateurs d'accès le permettent. Sinon, nous pouvons les utiliser comme nous le faisons par Hasa-relation. Et a une relation n'est pas l'héritage. Encore une fois, nous ne pouvons pas remplacer la méthode statique. Si nous pouvons utiliser une autre méthode, mais que nous ne pouvons pas la remplacer, il s’agit d’une relation HasA. Si nous ne pouvons pas les remplacer, ce ne sera pas un héritage. Le rédacteur était donc correct à 100%.
Tous les membres publics et protégés peuvent être hérités de toute classe, tandis que les membres par défaut ou du package peuvent également l'être de la classe au sein du même package que celui de la superclasse. Cela ne dépend pas s'il s'agit d'un membre statique ou non statique.
Mais il est également vrai que la fonction membre statique ne participe pas à la liaison dynamique. Si la signature de cette méthode statique est identique dans les classes parent et enfant, le concept de Shadowing s'applique, pas de polymorphisme.
Les méthodes statiques en Java sont héritées, mais ne peuvent pas être remplacées. Si vous déclarez la même méthode dans une sous-classe, vous masquez la méthode superclass au lieu de la remplacer. Les méthodes statiques ne sont pas polymorphes. Au moment de la compilation, la méthode statique sera liée statiquement.
Exemple:
public class Writer {
public static void write() {
System.out.println("Writing");
}
}
public class Author extends Writer {
public static void write() {
System.out.println("Writing book");
}
}
public class Programmer extends Writer {
public static void write() {
System.out.println("Writing code");
}
public static void main(String[] args) {
Writer w = new Programmer();
w.write();
Writer secondWriter = new Author();
secondWriter.write();
Writer thirdWriter = null;
thirdWriter.write();
Author firstAuthor = new Author();
firstAuthor.write();
}
}
Vous obtiendrez ce qui suit:
Writing
Writing
Writing
Writing book
La méthode statique est héritée dans la sous-classe mais ce n'est pas du polymorphisme. Lorsque vous écrivez l'implémentation de la méthode statique, la méthode de la classe du parent est masquée et non remplacée. Pensez, si ce n’est pas hérité, comment vous pouvez y accéder sans classname.staticMethodname();
?
Vous pouvez remplacer les méthodes statiques, mais si vous essayez d'utiliser le polymorphisme, elles fonctionnent selon la portée de la classe (contrairement à ce à quoi nous nous attendions normalement).
public class A {
public static void display(){
System.out.println("in static method of A");
}
}
public class B extends A {
void show(){
display();
}
public static void display(){
System.out.println("in static method of B");
}
}
public class Test {
public static void main(String[] args){
B obj =new B();
obj.show();
A a_obj=new B();
a_obj.display();
}
}
Dans le premier cas, o/p est "dans la méthode statique de B" # annulation réussie Dans le deuxième cas, o/p est "dans la méthode statique de A" # Méthode statique - ne tiendra pas compte du polymorphisme
Les méthodes statiques sont héritées en Java mais elles ne participent pas au polymorphisme. Si nous essayons de remplacer les méthodes statiques, elles masqueront simplement les méthodes statiques de la superclasse au lieu de les remplacer.