JavaRush /Java Blog /Random-IT /Analisi di domande e risposte da interviste per sviluppat...

Analisi di domande e risposte da interviste per sviluppatori Java. Parte 4

Pubblicato nel gruppo Random-IT
Ciao a tutti, oggi continuo ad analizzare oltre 250 domande di interviste per sviluppatori Java. Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 1Parti precedenti dell'analisi: prima , seconda , terza . Quindi continuiamo.

29. È possibile utilizzare return in un costruttore?

Puoi, ma senza il valore di ritorno per il diritto alla restituzione . Cioè, puoi usare return; come costruzione ausiliaria durante i calcoli nel costruttore per terminare (interrompere) urgentemente l'esecuzione di ulteriore codice e completare l'inizializzazione dell'oggetto. Ad esempio, abbiamo una classe Cat e se Cat is homeless - isHomeless = true , dobbiamo completare l'inizializzazione e non compilare altri campi (dopotutto, ci sono sconosciuti, poiché il gatto è senza casa):
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
Ma quando si tratta di valori specifici, un costruttore non può utilizzare return per restituire un valore perché:
  • quando dichiari un costruttore non avrai nulla che assomigli a un tipo restituito;
  • In genere, il costruttore viene chiamato implicitamente durante l'istanziazione;
  • Un costruttore non è un metodo: è un meccanismo separato il cui unico scopo è inizializzare le variabili di istanza e l' operatore new è responsabile della creazione di un oggetto .
Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 2

30. È possibile lanciare un'eccezione da un costruttore?

I costruttori gestiscono le eccezioni esattamente allo stesso modo dei metodi. E se i metodi ci consentono di lanciare eccezioni scrivendo Throws <ExceptionType> nell'intestazione del metodo , allora il costruttore ci consente di farlo e anche quando ereditiamo e definiamo un costruttore erede, possiamo espandere il tipo di eccezione. Ad esempio, IOException -> Eccezione (ma non viceversa). Come esempio per lanciare un'eccezione da parte di un costruttore, prendiamo la classe Cat . Diciamo che al momento della creazione vogliamo inserire nome ed età da console:
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
Poiché reader.readLine() lancia una IOException, la specifichiamo nell'intestazione come possibile eccezione lanciata.

31. Da quali elementi è composta l'intestazione della classe? Scrivi un esempio

Parlando degli elementi che compongono l'intestazione della classe, diamo un'occhiata a un piccolo diagramma:
  • i componenti obbligatori saranno tra parentesi <>
  • facoltativo - in {}
{modificatore di accesso alla classe}{staticità della classe}{finalità della classe}{astrazione della classe} <nome classe>{ereditarietà dalla classe genitore} {implementazione dell'interfaccia} Quindi, quello che abbiamo: {class access modifier} - solo i modificatori public e il modificatore di accesso mancante, ovvero default , sono disponibili per la class . {class static} - static è un modificatore che indica che questa classe è statica, applicabile solo alle classi interne (classi all'interno di altre classi). {finalità della classe} - come ricordiamo, questo è il modificatore finale , in presenza del quale la classe diventa non ereditabile (esempio dal riquadro - String ). {astrazione della classe} - modificatore - abstract , che indica che questa classe potrebbe avere metodi non implementati. Questo modificatore è in conflitto con il modificatore finale , cioè solo uno di essi può essere nell'intestazione della classe, poiché il modificatore astratto implica che la classe data verrà ereditata e le sue parti astratte verranno implementate. E final indica che questa è la versione finale (finale) della classe e non può essere ereditata. In realtà, utilizzare entrambi i modificatori contemporaneamente sarebbe assurdo e il compilatore non ce lo permetterà. <class> è una parola chiave obbligatoria che indica una dichiarazione di classe. <nome classe> è un nome di classe semplice, che è l'identificatore di una classe Java specifica. Il nome completo della classe è costituito dal nome completo del pacchetto + . + nome della classe semplice. {ereditarietà dalla classe genitore} : specifica la classe genitore (se presente) utilizzando la parola chiave extends . Ad esempio, .. estende ParentClass . {implementazione dell'interfaccia} - specificando le interfacce che questa classe implementa (se presenti) utilizzando la parola chiave implements . Ad esempio: ... implementa FirstInterface, SecondInterface ... Bene, come esempio di intestazione di classe, considera l'intestazione della classe Lion , che eredita da Cat e implementa l' interfaccia WildAnimal :
public final class Lion extends Cat implements WildAnimal
Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 3

32. Da quali elementi è composta l'intestazione del metodo? Scrivi un esempio

Ancora una volta, quando osservi gli elementi che compongono l'intestazione di un metodo, considera un piccolo diagramma in cui:
  • i componenti obbligatori sono tra parentesi <>
  • facoltativo - in {}
{modificatore di accesso}{metodo statico}{astrazione del metodo}{finalità del metodo}{modificatore di sincronizzazione} {modificatore nativo<valore restituito><nome metodo> <(> {argomenti del metodo} <)>{eccezioni lanciate} {modificatore di accesso } — tutti i modificatori di accesso sono disponibili per il metodo: public , protected , default , private . {metodo statico} - statico è un modificatore che indica che questo metodo è statico, cioè non è legato a un oggetto, ma a una classe. {astrazione del metodo} è il modificatore astratto , che indica che non esiste alcuna implementazione (corpo) del metodo. Per un corretto funzionamento è necessario anche un modificatore astratto per la classe in cui viene fornito il metodo. Come nell'intestazione della classe, questo modificatore è in conflitto con il modificatore finale , ma in aggiunta ad esso, è in conflitto anche con il modificatore statico , perché un metodo astratto implica la sovrascrittura del metodo nel discendente e i metodi statici non vengono sovrascritti. {finalità del metodo} - final - un modificatore che indica che questo metodo non può essere sovrascritto. {modificatore di sincronizzazione} - sincronizzato - un modificatore che significa che questo metodo è protetto dall'accesso simultaneo ad esso da diversi thread. Se il metodo non è statico, si chiude sul mutex this dell'oggetto. Se il metodo è statico, si chiude sul mutex della classe corrente. {modificatore nativo} - nativo - questo modificatore indica che il metodo è scritto in un linguaggio di programmazione diverso. <valore restituito> è il tipo di valore che il metodo dovrebbe restituire. Se non dovesse restituire nulla, void . <nome metodo> è il nome del metodo, il suo identificatore nel sistema. {argomenti del metodo} sono gli argomenti (parametri) che il metodo accetta: sono necessari per implementarne le funzionalità. {eccezioni lanciabili} - ThrowsExceptionType - un elenco di eccezioni verificate che questo metodo può lanciare. E come esempio di intestazione di metodo, darò questo:
public static void main(String[] args) throws IOException

33. Crea un costruttore predefinito nell'oggetto discendente se non è definito nell'oggetto base (ma è definito un altro costruttore)

Non capisco appieno la domanda in sé, ma forse significa che, ad esempio, nel genitore abbiamo qualche costruttore personalizzato:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Pertanto, nella classe antenata, dobbiamo assolutamente definire un costruttore che riempirà (chiamerà) il costruttore genitore:
public  class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 4

34. Quando viene utilizzata la parola chiave this?

In Java, questo ha due significati diversi. 1. Come riferimento all'oggetto corrente, come this.age = 9 . Cioè, questo si riferisce all'oggetto su cui è stato chiamato e al quale fa riferimento il codice che lo utilizza . La funzione principale è aumentare la leggibilità del codice ed evitare ambiguità. Ad esempio, se il nome del campo della classe interna e l'argomento del metodo sono gli stessi:
public void setName(String name) {
   this.name = name;
}
Ciò significa che this.name è un campo del nome dell'oggetto e un argomento del metodo. Il riferimento this non può essere utilizzato nei metodi statici. 2. questo può essere utilizzato in un costruttore sotto forma di chiamata al metodo, come this(value) . In questo caso si tratterà di una chiamata ad un altro costruttore della stessa classe. In breve, puoi chiamare due costruttori contemporaneamente quando crei un oggetto:
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
Quando viene creato un oggetto Cat e viene chiamato il primo costruttore, entrambi i campi dell'oggetto verranno chiamati e inizializzati con successo. Ci sono un paio di sfumature:
  1. this() funziona solo nel costruttore.
  2. Un riferimento a un altro costruttore deve trovarsi nella prima riga del blocco costruttore (corpo). Pertanto, più di un (altro) costruttore di una determinata classe non può essere chiamato in un costruttore.
Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 5Altri esempi sono in questo articolo .

35. Cos'è un inizializzatore?

Per quanto ho capito, in questa domanda stiamo parlando di blocchi di inizializzazione ordinari e statistici. Innanzitutto, ricordiamo cos'è l'inizializzazione. L'inizializzazione è creazione, attivazione, preparazione al lavoro, determinazione dei parametri. Portare un programma o un componente in uno stato di pronto per l'uso. Come ricorderete, durante la creazione dell'oggetto, una variabile di classe può essere inizializzata direttamente al momento della dichiarazione:
class Cat {
   private int age = 9;
   private  String name = "Tom";
Oppure impostalo esternamente tramite un costruttore:
class Cat {
   private int age;
   private  String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
Ma c'è un altro modo: impostare una variabile oggetto interna tramite un blocco di inizializzazione, che assomiglia a parentesi graffe { } all'interno della classe, senza nome (come un metodo o un costruttore):
class Cat {
   private int age;
   private  String name;

   {
       age = 10;
       name = "Tom";
   }
Cioè, un blocco di inizializzazione è un pezzo di codice che viene caricato quando viene creato un oggetto. In genere, tali blocchi vengono utilizzati per eseguire alcuni calcoli complessi necessari durante il caricamento di una classe. I risultati di questi calcoli possono essere specificati come valori per le variabili. Inoltre, oltre ai normali blocchi di inizializzazione, ce ne sono di statici, che sembrano uguali, ma hanno la parola chiave static prima della parentesi graffa :
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
Questo blocco è esattamente uguale al precedente. Ma se quello normale viene attivato quando ciascun oggetto viene inizializzato, quello statico si attiverà solo una volta, quando la classe viene caricata. In un tale blocco, di norma, vengono eseguiti anche alcuni calcoli complessi per la successiva inizializzazione delle variabili di classe statiche. A un blocco statico si applicano le stesse restrizioni dei metodi statici: non può utilizzare dati non statici, così come un riferimento all'oggetto corrente - this . Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 6Successivamente, possiamo vedere l'ordine di inizializzazione della classe (insieme al suo antenato) per una migliore comprensione del momento in cui vengono attivati ​​i blocchi di inizializzazione.

36. Per ereditare una classe pubblica, la classe Child estende Parent, scrivere l'ordine di inizializzazione dell'oggetto

Quando viene caricata la classe Child, l'ordine di inizializzazione sarà il seguente:
  1. Campi statici della classe Parent .
  2. Blocco di inizializzazione statico per la classe Parent .
  3. Campi statici della classe Child .
  4. Blocco di inizializzazione statico per la classe Child .
  5. Campi non statici della classe Parent .
  6. Non un blocco di inizializzazione statico per la classe Parent .
  7. Costruttore per la classe Parent .
  8. Campi non statici della classe Child .
  9. Non un blocco di inizializzazione statico per la classe Child .
  10. Costruttore della classe Child .
Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 7Ecco un breve articolo che spiega nella pratica l'ordine di inizializzazione.

37. Quali relazioni conosci tra classi (oggetti)?

Esistono due tipi di relazioni tra le classi in Java:
  • È-una relazione
Il principio IS-A nell'OOP si basa sull'ereditarietà delle classi o sull'implementazione dell'interfaccia. Ad esempio, se la classe Lion eredita da Cat , diciamo che Lion è Cat :
Lion IS-A Cat
(ma non tutti i gatti sono un leone ) La situazione è esattamente la stessa con le interfacce. Se la classe Lion implementa l' interfaccia WildAnimal , anche loro sono in una relazione:
Lion IS-A WildAnimal
  • Relazioni HA-A
Questo tipo di rapporto si basa sull'utilizzo di classi da parte di altre classi, detto anche “associazione”. Un'associazione è una classe che fa riferimento a un'altra classe (o anche a un'altra classe). Ad esempio, la classe Car potrebbe fare riferimento alla classe Passenger e questa sarebbe la relazione:
Car HAS-A Passenger
E viceversa: se Passenger ha un riferimento a Car , allora questa sarà la relazione:
Passenger HAS-A Car

38. Quali connessioni associative tra oggetti conosci?

Aggregazione e composizione non sono altro che casi particolari di associazione. L'aggregazione è una relazione in cui un oggetto è parte di un altro. Ad esempio, un passeggero potrebbe trovarsi in un'auto. Inoltre, potrebbero esserci più passeggeri o non esserci affatto (se stiamo parlando di una Tesla, l'autista non è richiesto). Per esempio:
public class Car {
   private List passengers = new ArrayList<>();

 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }

   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Перевозка пассажира - " + passenger.toString());
       }
       passengers.clear();
   }
}
Cioè, non ci interessa il numero di passeggeri (o se ce ne sono): la funzionalità della classe Auto non dipende da questo. L'aggregazione implica anche che quando un oggetto viene utilizzato da un altro oggetto, il primo può essere utilizzato in altri oggetti. Ad esempio, lo stesso studente può essere membro sia di un club di maglieria che di un gruppo musicale di rocker e allo stesso tempo frequentare un gruppo di studenti di inglese. Come hai capito, l'aggregazione è una relazione associativa più libera tra le classi. Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 8La composizione è un rapporto ancora più rigido quando un oggetto non solo è parte di un altro oggetto, ma il lavoro dell'altro oggetto dipende molto dal primo. Ad esempio, il motore di un'auto. Sebbene il motore possa esistere senza l’auto, è inutile al di fuori di essa. Ebbene, un'auto non può funzionare senza motore:
public class Car {
   private Engine engine;

   public Car(Engine engine) {
       this.engine = engine;
   }

   void startMoving() {
       engine.start();
           ...
   }
La composizione implica anche che quando un oggetto viene utilizzato da un altro oggetto, il primo non può appartenere a nessun altro. Se torniamo al nostro esempio, un motore può appartenere solo a un'auto, ma non a due o più contemporaneamente. Probabilmente ci fermeremo qui oggi.Analisi di domande e risposte da interviste per sviluppatori Java.  Parte 4 - 9
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION