JavaRush /Java Blog /Random-IT /Livello 24. Risposte alle domande dell'intervista sull'ar...
zor07
Livello 31
Санкт-Петербург

Livello 24. Risposte alle domande dell'intervista sull'argomento del livello

Pubblicato nel gruppo Random-IT
Livello 24. Risposte alle domande dell'intervista sull'argomento del livello - 1
  1. A cosa servono le classi interne anonime?

    Le classi interne anonime vengono compilate in file внешнийКласс$n.class. Al posto della classe esterna c'è quindi il nome della classe framing, all'interno della quale viene descritta la classe interna anonima. Al posto n è un numero da 1 al numero di classi anonime.

  2. È possibile ereditare le classi interiori?

    È possibile ereditare classi interiori da altri.

    L'ereditarietà da una classe interna è un po' più complicata del solito, poiché il costruttore della classe interna è associato ad un riferimento all'oggetto esterno circostante. Il problema è che il riferimento all'oggetto "nascosto" della classe esterna che lo racchiude deve essere inizializzato e non esiste più un oggetto che lo racchiude predefinito nella classe derivata. Per indicare esplicitamente l'oggetto esterno che lo racchiude, viene utilizzata una sintassi speciale:

    //: innerclasses/InheritInner.java
    // Наследование от внутреннего класса.
    
    class WithInner {
      class Inner {}
    }
    
    public class InheritInner extends WithInner.Inner {
      //! InheritInner() {} // He компorруется
      InheritInner(WithInner wi) {
        wi.super();
      }
      public static void main(String[] args) {
        WithInner wi = new WithInner();
        InheritInner ii = new InheritInner(wi);
      }
    }

    Qui la classe InheritInnerestende solo la classe interna e non quella esterna. Ma quando si tratta di creare un costruttore, il costruttore predefinito fornito non è adatto e non è possibile passare semplicemente un riferimento a un oggetto esterno. È necessario includere un'espressione nel corpo del costruttore linkНаОбъемлющийКласс.super();. Fornirà il collegamento mancante e il programma verrà compilato.

  3. È possibile ereditare classi interne anonime?

    Descrivendo una classe anonima, stiamo già ereditando da qualche classe o implementando qualche interfaccia. Le parole extends o implements non possono essere applicate direttamente alle classi anonime, ma nessuno si preoccupa di preparare ed estendere in anticipo l'interfaccia richiesta, che implementeremo utilizzando una classe anonima. Un esempio nel codice seguente.

    import java.awt.event.WindowListener;
    
    public class TestExtendAnonym {
        private interface MyInterface extends Runnable, WindowListener {
        }
    
        Runnable r = new MyInterface() {
        ...
        //Пример того How реализовать 2 и более интерфейса в анонимном классе
        };
    }

    Non puoi ereditare da una classe anonima.

  4. È possibile ignorare le classi interne?

    Sovrascrivere la classe interna come se fosse un altro metodo della classe esterna in realtà non ha alcun effetto:

    //: innerclasses/BigEgg.java
    // Внутренний класс нельзя переопределить
    // подобно обычному методу,
    import static net.mindview.util.Print.*;
    
    class Egg {
      private Yolk y;
      protected class Yolk {
        public Yolk() { print("Egg.Yolk()"); }
      }
      public Egg() {
        print("New Egg()");
        y = new Yolk();
      }
    }
    
    public class BigEgg extends Egg {
      public class Yolk {
        public Yolk() { print("BigEgg.Yolk()"); }
      }
      public static void main(String[] args) {
        new BigEgg();
      }
    }

    Conclusione:

    New Egg()
    Egg.Yolk()

    Il costruttore predefinito viene sintetizzato automaticamente dal compilatore e chiama il costruttore predefinito dalla classe base. Potresti pensare che quando si crea un oggetto BigEggsi debba utilizzare una classe “override” Yolk, ma non è affatto così, come si può vedere dal risultato del programma.

    Questo esempio mostra semplicemente che quando si eredita da una classe esterna, non accade nulla di speciale alle classi interne. Le due classi interne sono entità completamente separate, con spazi dei nomi indipendenti. In altre parole, è impossibile.

  5. Quali sono i limiti delle lezioni locali?

    Innanzitutto, ricordiamo cos'è una lezione locale. Questa è una classe descritta in un blocco di codice, cioè in termini semplici - tra virgolette {}. Molto spesso queste citazioni sono il corpo del metodo. Ma possono anche essere semplicemente un blocco, un blocco statico, un corpo ifdi -s, loop, ecc.

    La classe locale è dotata delle caratteristiche delle classi interne, ma ha caratteristiche distintive, vale a dire:

    1. он имеет доступ только к финальным полям и аргументам обрамляющего метода, а также ко всем полям обрамляющего класса, в том числе приватным и статическим;
    2. локальный класс виден и может создаваться только в блоке, в котором описан;
    3. у локального класса не ставится модификатор доступа;
    4. не может иметь статических полей, методов, классов (за исключением финальных);
    5. локальный класс, объявленный в статическом блоке может обращаться только к статическим полям внешнего класса.

    Но! Начиная с Java8 мы можем обращаться в локальных классах к не финальным локальным переменным, если они не были изменены до момента инициализации класса. Также теперь стало возможным обращение к не финальным параметрам метода.

  6. Может ли анонимный внутренний класс содержать статические методы?

    Нет. У Анонимных внутренних классов, How и у внутренних классов не может быть статических полей, методов. (вспомним, что анонимные классы компorруются в обычные внутренние, а те, в свою очередь, связаны с an objectом обрамляющего класса)

  7. Можно ли создать an object внутреннего класса, если у внешнего класса только private конструктор?

    Имея подобный code:

    public class PrivateConst {
        private PrivateConst() {}
        public class InnerClass{
            public void f(){
                System.out.println("hello");
            }
       }
    }

    Напрямую, в другом классе (вне обрамляющего), конечно, создать an object InnerClass следующим способом не получится:

    PrivateConst.InnerClass priv = new PrivateConst().new InnerClass();

    Но! What если у нас есть метод, возвращающий экземпляр

    PrivateConst:public class PrivateConst {
        private static PrivateConst instance;
        private PrivateConst() {}
    
        public static PrivateConst getInstance(){
            instance = new PrivateConst();
            return instance;
        }
    
        public class InnerClass{}
    }

    В этом случае приватный конструктор нам не помеха для создания an object InnerClass. Так же мы без проблем сможем создавать его в методах и в других внутренних классах, принадлежащих PrivateConst. Ответ — можно, если Howим-либо способом нам удастся получить an object обрамляющего класса.

  8. Можно ли объявлять внутренние классы private?

    Да, можно.

    PS Обоснования так и не нашел, но на философии java встречались подобные примеры. Плюс IDE не ругается. Буду признателен за обоснование, но предположу, что в этом плане внутренний класс ничем не отличается от обычного класса.

  9. Можно ли объявлять анонимные внутренние классы private?

    Аналогично (в плане не нашел обоснования). Можно объявить private переменную от типа которой наследуется наш анонимный класс.

  10. Сколько у класса максимально может быть внутренних классов?

    Сколь угодно много. Ограничение особенности ОС и длинны имени файлов.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION