CodeGym /Blog Java /Random-FR /Explorer les questions et réponses d'un entretien d'embau...
John Squirrels
Niveau 41
San Francisco

Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java. Partie 4

Publié dans le groupe Random-FR
Bonjour à tous! Aujourd'hui, je poursuis mon examen des questions d'entretien pour les développeurs Java. Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 - 1

29. Le retour peut-il être utilisé dans un constructeur ?

Oui, mais uniquement sans valeur à droite du mot-clé return . Vous pouvez utiliser return ; comme instruction d'assistance dans un constructeur pour terminer (interrompre) de toute urgence l'exécution de code supplémentaire et terminer l'initialisation de l'objet. Par exemple, supposons que nous ayons une classe Cat , et si un chat est sans abri ( isHomeless = true , alors nous voulons terminer l'initialisation et ne pas remplir les autres champs (après tout, ils nous sont inconnus, puisque le chat est sans abri) :

public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
Mais si nous parlons de valeurs concrètes, alors le mot-clé return ne peut pas renvoyer une valeur spécifique car :
  • lorsque vous déclarez un constructeur, vous n'aurez rien de comparable au type de retour ;
  • en règle générale, le constructeur est implicitement appelé lors de l'instanciation ;
  • le constructeur n'est pas une méthode : c'est un mécanisme distinct dont le seul but est d'initialiser des variables d'instance, c'est-à-dire que nous utilisons l' opérateur new pour créer un objet.
Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 - 2

30. Une exception peut-elle être levée depuis un constructeur ?

Les constructeurs fonctionnent avec les exceptions de la même manière que les méthodes. Les méthodes nous permettent de lever des exceptions en écrivant throws <ExceptionType> dans l'en-tête de la méthode. Et les constructeurs nous permettent de faire de même. Lorsque nous héritons et définissons le constructeur d'une classe enfant, nous pouvons élargir le type d'exception — par exemple, IOException -> Exception (mais pas l'inverse). Utilisons le constructeur de la classe Cat comme exemple de constructeur lançant une exception. Disons que lorsque nous créons un objet, nous souhaitons saisir le nom et l'âge depuis la console :

public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
Puisque reader.readLine() renvoie une IOException, nous l'écrivons dans l'en-tête comme une possible exception levée.

31. Quels sont les éléments d’un en-tête de classe ? Écrivez un exemple

Pour illustrer les éléments qui composent un en-tête de classe, regardons un petit schéma :
  • les éléments obligatoires apparaissent entre parenthèses <>
  • les éléments facultatifs sont dans {}
{modificateur d'accès}{static}{final}{abstract}<nom de classe>{héritage de la classe parent}{implémentation des interfaces} Donc, ce que nous avons : { modificateur d'accès} — seuls les modificateurs d'accès public et par défaut sont disponibles pour le classe. {static} — le modificateur static indique que cette classe est statique ; cela s'applique uniquement aux classes internes (classes à l'intérieur d'autres classes). {final} — c'est bien sûr le modificateur final , qui rend la classe non héritable (un exemple prêt à l'emploi est String ). {abstract} — le modificateur abstrait , qui indique que la classe peut avoir des méthodes non implémentées. Ce modificateur est en conflit avec le modificateur final . L'en-tête de classe ne peut en avoir qu'un seul puisque le modificateur abstrait signifie que la classe sera héritée et que ses éléments abstraits seront implémentés. Mais final indique qu’il s’agit de la version finale de la classe et qu’elle ne peut pas être héritée. En fait, utiliser simultanément les deux modificateurs serait absurde. Le compilateur ne nous permet pas de faire cela. <class> est un mot-clé obligatoire qui indique une déclaration de classe. <class name> est un simple nom de classe qui devient l'identifiant d'une classe Java spécifique. Le nom de classe complet se compose du nom qualifié du package plus '.' plus le nom simple de la classe. {héritage de la classe parent} est une indication de la classe parent (le cas échéant) à l'aide du mot clé extends . Par exemple, ... étend ParentClass . {implémentation des interfaces} — une liste des interfaces que cette classe implémente (le cas échéant), à l'aide du mot-clé Implements . Par exemple : ... implémente FirstInterface, SecondInterface ... À titre d'exemple, considérons l'en-tête de classe Lion , qui hérite de Cat et implémente l' interface WildAnimal :

public final class Lion extends Cat implements WildAnimal
Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 - 3

32. Quels sont les éléments d’un en-tête de méthode ? Écrivez un exemple

Lorsque nous considérons les éléments qui composent un en-tête de méthode, considérons à nouveau un petit schéma :
  • les éléments obligatoires apparaissent entre parenthèses <>
  • les éléments facultatifs sont dans {}
{modificateur d'accès}{static}{abstract}{final}{synchronized} {natif} <valeur de retour><nom de la méthode> <(>{paramètres de la méthode}<}>{lancer des exceptions} {modificateur d'accès} — tous les modificateurs d' accès sont disponible pour la méthode — public , protected , default , private . {static} — le modificateur static , qui indique que la méthode est statique et donc associée à la classe, et non à un objet. {abstract} — le modificateur abstrait , qui indique que la méthode n'a pas d'implémentation (corps). Pour fonctionner correctement, la classe qui déclare la méthode doit également avoir le modificateur abstrait . Comme dans l'en-tête de classe, ce modificateur entre en conflit avec le modificateur final , ainsi qu'avec le modificateur statique , car un La méthode abstraite implique le remplacement de la méthode dans un descendant, et les méthodes statiques ne peuvent pas être remplacées. {finale} — le modificateur final , qui indique que cette méthode ne peut pas être remplacée. {synchronized} — le modificateur synchronisé , ce qui signifie que la méthode est protégée contre accès simultané à partir de différents threads. Si la méthode n'est pas statique, elle est fermée pour ce mutex de l'objet. Si la méthode est statique, alors elle est fermée pour le mutex de la classe actuelle. {native} — le modificateur natif indique que la méthode est écrite dans un autre langage de programmation. <type de retour> — le type de valeur que la méthode doit renvoyer. Si la méthode ne renvoie rien, alors void . <nom de la méthode> — le nom de la méthode, c'est-à-dire son identifiant dans le système. {paramètres de la méthode} — les paramètres que la méthode accepte : ils sont nécessaires pour implémenter sa fonctionnalité. {exceptions levées}renvoie <ExceptionType> — une liste des exceptions vérifiées que cette méthode peut lever. Je vais proposer ce qui suit comme exemple d'en-tête de méthode :

public static void main(String[] args) throws IOException

33. Créez un constructeur par défaut dans une classe enfant s'il n'en est pas déjà défini dans la classe de base (mais qu'un constructeur différent est défini)

Je ne suis pas sûr de bien comprendre la question, mais cela signifie peut-être que nous avons un constructeur comme celui-ci dans la classe parent :

public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Dans ce cas, dans la classe parent, nous devons absolument définir un constructeur qui initialisera le parent (c'est-à-dire appellera le constructeur parent) :

public class Lion extends Cat {
 
   public Lion(int age, String name) {
       super(age, name);
   }
}
Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 - 4

34. Quand le mot-clé this est-il utilisé ?

En Java, cela a deux significations différentes. 1. C'est une référence à l'objet actuel, par exemple this.age = 9 . Autrement dit, this fait référence à l'objet dans lequel il est utilisé et auquel le code correspondant fait référence. L'objectif principal est d'améliorer la lisibilité du code et d'éviter toute ambiguïté. Par exemple, si un champ d'instance et un argument de méthode portent le même nom :

public void setName(String name) {
   this.name = name;
}
Autrement dit, this.name est le champ de l'objet, tandis que name est le paramètre de la méthode. La référence this ne peut pas être utilisée dans les méthodes statiques. 2. Dans le constructeur, this ( value) peut être appelé comme une méthode, par exemple this(value) . Dans ce cas, il s’agira d’un appel à un autre constructeur de la même classe. Fondamentalement, vous pouvez appeler deux constructeurs pendant le processus de création d'un objet :

public Cat(int age, String name) {
   this(name);
   this.age = age;
}
 
public Cat(String name) {
   this.name = name;
}
Lors de l'appel du premier constructeur pour créer un objet Cat , les deux champs d'instance seront initialisés avec succès. Il y a quelques nuances ici :
  1. this() ne fonctionne que dans un constructeur.
  2. Une référence à un autre constructeur doit figurer dans la première ligne du bloc constructeur (corps). Cela signifie qu'un constructeur ne peut pas appeler plus d'un (autre) constructeur de sa classe.
Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 - 5

35. Qu'est-ce qu'un initialiseur ?

Autant que je sache, cette question concerne les blocs d'initialisation ordinaires et statiques. Rappelons d'abord ce qu'est l'initialisation. L'initialisation est la création, l'activation, la préparation et la définition de champs. Préparer un programme ou un composant pour qu'il soit prêt à l'emploi. Vous vous souviendrez que lorsque vous créez un objet, une variable de classe peut être initialisée immédiatement lorsqu'elle est déclarée :

class Cat {
   private int age = 9;
   private String name = "Tom";
Ou défini après coup via le constructeur :

class Cat {
   private int age;
   private String name;
 
   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
Mais il existe une autre manière : vous pouvez définir une variable d'instance à l'aide d'un bloc d'initialisation, qui prend la forme d'accolades {} à l'intérieur d'une classe, sans nom (comme une méthode ou un constructeur sans nom) :

class Cat {
   private int age;
   private String name;
 
   {
       age = 10;
       name = "Tom";
   }
Un bloc d'initialisation est un morceau de code chargé lors de la création d'un objet. De tels blocs sont généralement utilisés pour effectuer certains calculs complexes requis lors du chargement d’une classe. Les résultats de ces calculs peuvent être définis comme valeurs de variables. En plus des blocs d'initialisation ordinaires, il existe des blocs statiques. Ils se ressemblent mais ont le mot-clé static devant l’accolade ouvrante :

class Cat {
   private static int age;
   private static String name;
 
   static{
       age = 10;
       name = "Tom";
   }
Ce bloc est le même que le précédent. Mais si l'objet ordinaire est exécuté lorsque chaque objet est initialisé, alors l'objet statique n'est exécuté qu'une seule fois, lorsque la classe est chargée. En règle générale, certains calculs complexes sont effectués dans un bloc statique, utilisé pour initialiser les variables de classe statiques. Les mêmes restrictions s'appliquent à un bloc statique qui s'appliquent aux méthodes statiques : vous ne pouvez pas utiliser de données non statiques, telles qu'une référence à l'objet actuel ( this ) dans un bloc statique. Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 à 6Nous pouvons maintenant examiner l'ordre d'initialisation de la classe (avec sa classe parent) afin de mieux comprendre quand exactement les blocs d'initialisation sont invoqués.

36. Étant donné une classe publique Child qui étend Parent, écrivez l'ordre d'initialisation de l'objet

Lors du chargement de la classe Child , l'ordre d'initialisation sera le suivant :
  1. Champs de classe statique de la classe Parent .
  2. Bloc d'initialisation statique de la classe Parent .
  3. Champs statiques de la classe Сhild .
  4. Bloc d'initialisation statique de la classe Child .
  5. Champs non statiques de la classe Parent .
  6. Bloc d'initialisation non statique de la classe Parent .
  7. Constructeur de classe parent .
  8. Champs non statiques de la classe Сhild .
  9. Bloc d'initialisation non statique de la classe Сhild .
  10. Le constructeur de la classe Сhild .
Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 4 à 7

37. Quel genre de relations entre les classes (objets) connaissez-vous ?

Il existe deux types de variables en Java : les types primitifs et les références à des objets à part entière.
  • Relations IS-A
Le principe IS-A de la POO est basé sur l'héritage de classe ou l'implémentation d'interfaces. Par exemple, si la classe Lion hérite de Cat , alors on dit que Lion est un Cat :

Lion IS-A Cat
(mais tous les chats ne sont pas des Lions ) La même situation existe avec les interfaces. Si la classe Lion implémente l' interface WildAnimal , alors elles existent également dans la relation :

Lion IS-A WildAnimal
  • Relation HAS-A
Ce type de relation est celui où une classe utilise d’autres classes, également appelée « association ». Une association est une classe qui fait référence à une autre classe (ou à des références mutuelles). Par exemple, la classe Car peut faire référence à la classe Passager , ce qui constituerait la relation suivante :

Car HAS-A Passenger
Et vice versa : si Passenger a une référence à Car , alors ce sera la relation :

Passenger HAS-A Car

38. Quelles relations d'objet associatives connaissez-vous ?

L'agrégation et la composition ne sont que des cas particuliers d'association. L'agrégation est une relation dans laquelle un objet fait partie d'un autre. Par exemple, un passager peut se trouver dans une voiture. De plus, il peut y avoir plusieurs passagers, voire aucun (et si nous parlons de Tesla, il se peut qu'il n'y ait pas de conducteur). Par exemple:

public class Car {
   private List passengers = new ArrayList<>();
 
 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }
 
   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Transporting passenger - " + passenger.toString());
       }
       passengers.clear();
   }
}
En d'autres termes, le nombre de passagers (quel qu'il soit) n'est pas important pour nous : la fonctionnalité de la classe Car n'en dépend pas. L'agrégation implique également que lorsqu'un autre objet utilise un objet, le premier objet peut être utilisé par d'autres objets. Par exemple, le même élève peut faire partie à la fois d'un club de tricot et d'un groupe de rock et suivre simultanément un cours d'espagnol. Comme vous pouvez l'imaginer, l'agrégation est une relation associative plus lâche entre les classes. La composition est une relation encore plus étroite dans laquelle un objet fait non seulement partie d'un autre objet, mais où le travail d'un objet est très dépendant d'un autre. Par exemple, une voiture a un moteur. Un moteur peut exister sans voiture, mais il est inutile en dehors d’une voiture. Et une voiture ne peut pas fonctionner sans moteur :

public class Car {
   private Engine engine;
 
   public Car(Engine engine) {
       this.engine = engine;
   }
 
   void startMoving() {
       engine.start();
           ...
   }
La composition implique également que lorsqu'un autre objet utilise un objet, le premier objet ne peut appartenir à aucun autre objet. Pour revenir à notre exemple, un moteur ne peut appartenir qu’à une seule voiture, pas deux ou plus à la fois. Je pense que c'est suffisant pour aujourd'hui, alors nous allons nous arrêter ici.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION