Pourquoi atsortingbue-t-on une référence parent à l’object enfant en Java?

Je pose une question assez simple, mais je suis un peu confus à ce sujet.

Supposons que j’ai une classe Parent :

 public class Parent { int name; } 

Et avoir une autre classe Child.java :

 public class Child extends Parent{ int salary; } 

Et enfin ma classe Main.java

 public class Main { public static void main(Ssortingng[] args) { Parent parent = new Child(); parent.name= "abcd"; } } 

Si je fais un object enfant comme

 Child child = new Child(): 

L’object child peut alors accéder aux variables name and salary .

Ma question est:

 Parent parent = new Child(); 

donne access à la seule variable de name de la classe Parent. Alors, quelle est l’utilisation exacte de cette ligne?

  Parent parent = new Child(); 

Et aussi quand il utilise le polymorphism dynamic alors pourquoi la variable de classe enfant n’est pas accessible après cela

 Parent parent = new Child(); 

Tout d’abord, une clarification de la terminologie: nous assignons un object Child à une variable de type Parent . Parent est une référence à un object qui se trouve être un sous-type de Parent , un Child .

Ce n’est utile que dans un exemple plus compliqué. Imaginez que vous ajoutez getEmployeeDetails à la classe Parent:

 public Ssortingng getEmployeeDetails() { return "Name: " + name; } 

Nous pourrions remplacer cette méthode dans Child pour fournir plus de détails:

 @Override public Ssortingng getEmployeeDetails() { return "Name: " + name + " Salary: " + salary; } 

Maintenant, vous pouvez écrire une ligne de code qui obtient les détails disponibles, que l’object soit un Parent ou un Child :

 parent.getEmployeeDetails(); 

Le code suivant:

 Parent parent = new Parent(); parent.name = 1; Child child = new Child(); child.name = 2; child.salary = 2000; Parent[] employees = new Parent[] { parent, child }; for (Parent employee : employees) { employee.getEmployeeDetails(); } 

Entraînera la sortie:

 Name: 1 Name: 2 Salary: 2000 

Nous avons utilisé un Child comme Parent . Son comportement spécifique à la classe Child était spécifique, mais lorsque nous avons appelé getEmployeeDetails() nous pouvions ignorer la différence et nous concentrer sur la similarité des Parent et des Child . Ceci s’appelle le polymorphism de sous-type .

Votre question mise à jour demande pourquoi Child.salary n’est pas accessible lorsque l’object Child est stocké dans une référence Parent . La réponse est l’intersection du “polymorphism” et du “typage statique”. Parce que Java est statiquement typé au moment de la compilation, vous obtenez certaines garanties du compilateur mais vous êtes obligé de suivre des règles en échange ou le code ne sera pas compilé. Ici, la garantie pertinente est que chaque instance d’un sous-type (par exemple, Child ) peut être utilisée comme instance de son sur-type (par exemple, Parent ). Par exemple, lorsque vous accédez à employee.getEmployeeDetails ou à employee.name , vous êtes assuré que la méthode ou le champ est défini sur tout object non nul pouvant être affecté à une variable employee de type Parent . Pour faire cette garantie, le compilateur ne considère que ce type statique (en gros, le type de la référence de la variable, Parent ) lors de la décision de ce que vous pouvez accéder. Vous ne pouvez donc accéder à aucun membre défini sur le type d’exécution de l’object, Child .

Lorsque vous voulez vraiment utiliser un Child tant que Parent c’est une ressortingction facile à vivre et votre code sera utilisable pour Parent et tous ses sous-types. Si ce n’est pas acceptable, faites le type de l’ Child référence.

Il vous permet d’accéder à toutes les sous-classes via une interface parent commune. Cela est utile pour exécuter des opérations communes disponibles sur toutes les sous-classes. Un meilleur exemple est nécessaire:

 public class Shape { private int x, y; public void draw(); } public class Rectangle extends Shape { public void draw(); public void doRectangleAction(); } 

Maintenant si vous avez:

 List myShapes = new ArrayList(); 

Vous pouvez référencer chaque élément de la liste en tant que forme, vous n’avez pas à vous inquiéter s’il s’agit d’un rectangle ou d’un autre type, par exemple, Circle. Vous pouvez les traiter de la même façon; vous pouvez tous les dessiner. Vous ne pouvez pas appeler doRectangleAction parce que vous ne savez pas si la forme est vraiment un rectangle.

C’est un métier que vous faites entre le traitement d’objects de manière générique et le traitement spécifique.

Vraiment, je pense que vous devez en savoir plus sur la POO. Un bon livre devrait aider: http://www.amazon.com/Design-Patterns-Explained-Perspective-Object-Oriented/dp/0201715945

Si vous atsortingbuez le type de parent à une sous-classe, cela signifie que vous êtes d’accord pour utiliser les fonctionnalités communes de la classe parente.

Cela vous donne la liberté de vous abstenir de différentes implémentations de sous-classes. Par conséquent, vous êtes limité par les fonctionnalités parent.

Cependant, ce type d’affectation est appelé mise à niveau.

 Parent parent = new Child(); 

Le contraire est la baisse.

 Child child = (Child)parent; 

Ainsi, si vous créez une instance de Child et la redissortingbuez à Parent vous pouvez utiliser ce name atsortingbut. Si vous créez une instance de Parent vous pouvez faire la même chose qu’avec le cas précédent, mais vous ne pouvez pas utiliser le salary car il n’y a pas d’atsortingbut de ce type dans le Parent . Revenez au cas précédent qui peut utiliser le salary mais seulement en cas de baisse à l’ Child .

Il y a plus d’explication détaillée

Lorsque vous comstackz votre programme, la variable de référence de la classe de base obtient de la mémoire et le compilateur vérifie toutes les méthodes de cette classe. Donc, il vérifie toutes les méthodes de classe de base, mais pas les méthodes de classe enfant. Maintenant, au moment de la création de l’object, seules les méthodes vérifiées peuvent être exécutées. Si une méthode est remplacée dans la classe enfant exécutée. Les autres fonctions de classe enfant ne sont pas exécutées car le compilateur ne les a pas reconnues à la compilation.

C’est simple.

 Parent parent = new Child(); 

Dans ce cas, le type de l’object est Parent . Ant Parent n’a qu’une seule propriété. C’est le name

 Child child = new Child(); 

Et dans ce cas, le type de l’object est Child . Ant Child a deux propriétés. Ils sont name et salary .

Le fait est qu’il n’est pas nécessaire d’initialiser le champ non final immédiatement à la déclaration. Habituellement, cela se fait au moment de l’exécution, car souvent vous ne pouvez pas savoir exactement quelle mise en œuvre vous aurez besoin. Imaginons par exemple que vous ayez une hiérarchie de classe avec Transport classe en tête. Et trois sous-classes: Car , Helicopter et Boat . Et il y a un autre Tour classe qui a des Transport terrain. C’est:

 class Tour { Transport transport; } 

Tant qu’un utilisateur n’a pas réservé de voyage et n’a pas choisi un type de transport particulier, vous ne pouvez pas initialiser ce champ. C’est d’abord.

Deuxièmement, supposons que toutes ces classes doivent avoir une méthode go() mais avec une implémentation différente. Vous pouvez définir une implémentation de base par défaut dans la super-classe Transport et posséder des implémentations uniques dans chaque sous-classe. Avec cette initialisation Transport tran; tran = new Car(); Transport tran; tran = new Car(); vous pouvez appeler la méthode tran.go() et obtenir le résultat sans vous soucier de l’implémentation spécifique. Cela appellera la méthode outrepassée d’une sous-classe particulière.

De plus, vous pouvez utiliser une instance de sous-classe partout où une instance de superclasse est utilisée. Par exemple, vous souhaitez offrir la possibilité de louer votre transport. Si vous n’utilisez pas le polymorphism, vous devez écrire beaucoup de méthodes pour chaque cas: rentCar(Car car) , rentBoat(Boat boat) , etc. Dans le même temps, le polymorphism vous permet de créer une méthode de rent(Transport transport) universelle rent(Transport transport) . Vous pouvez y passer l’object de n’importe quelle sous-classe de Transport . De plus, si votre logique augmentera avec le temps et que vous devrez créer une autre classe dans la hiérarchie? En utilisant le polymorphism, vous n’avez rien à changer. Étendez simplement la classe Transport et transmettez votre nouvelle classe à la méthode:

 public class Airplane extends Transport { //implementation } 

et rent(new Airplane()) . Et new Airplane().go() dans le second cas.

Supposons que vous souhaitiez disposer d’un tableau d’instances de la classe Parent et d’un ensemble de classes enfant Child1, Child2, Child3 qui étend Parent. Il y a des situations où vous êtes uniquement intéressé par l’implémentation de la classe parente, qui est plus générale, et qui ne se soucient pas des choses plus spécifiques introduites par les classes enfants.

Cette situation se produit lorsque vous avez plusieurs implémentations. Laisse-moi expliquer. Supposons que vous ayez plusieurs algorithmes de sorting et que vous souhaitiez choisir lors de l’exécution celui que vous souhaitez implémenter ou que vous souhaitez donner à une autre personne la possibilité d’append son implémentation. Pour résoudre ce problème, vous créez généralement une classe abstraite (Parent) et une implémentation différente (Child). Si vous écrivez:

 Child c = new Child(); 

vous liez votre implémentation à la classe Child et vous ne pouvez plus la modifier. Sinon, si vous utilisez:

 Parent p = new Child(); 

tant que Child étend Parent, vous pouvez le modifier ultérieurement sans modifier le code.

La même chose peut être faite en utilisant des interfaces: Parent n’est plus une classe mais une interface Java.

En général, vous pouvez utiliser cette approche dans le modèle DAO où vous souhaitez avoir plusieurs implémentations dépendant de la firebase database. Vous pouvez regarder FactoryPatter ou AbstractFactory Pattern. J’espère que cela peut vous aider.

Vous déclarez le parent en tant que parent, donc Java ne fournira que les méthodes et les atsortingbuts de la classe Parent.

 Child child = new Child(); 

devrait marcher. Ou

 Parent child = new Child(); ((Child)child).salary = 1;