JavaRush /Java Blog /Random-TW /第 24 級。有關該級別主題的面試問題的答案
zor07
等級 31
Санкт-Петербург

第 24 級。有關該級別主題的面試問題的答案

在 Random-TW 群組發布
第 24 級。關於第 1 級主題的面試問題的答案
  1. 匿名內部類別編譯成什麼?

    匿名內部類別被編譯成внешнийКласс$n.class. 因此,取代外部類別的是框架類別的名稱,其中描述了匿名內部類別。n 是一個從 1 到匿名類別數量的數字。

  2. 內部類別可以繼承嗎?

    可以從其他類別繼承內部類別。

    從內部類別繼承比平常稍微複雜一些,因為內部類別的建構子與周圍外部物件的參考相關聯。問題是必須初始化封閉外部類別的「隱藏」物件引用,並且在衍生類別中不再有預設的封閉物件。為了明確指示封閉的外部對象,使用了特殊的語法:

    //: 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);
      }
    }

    這裡的類別InheritInner僅擴展內部類,而不擴展外部類。但是在建立建構函式時,提供的預設建構函式不合適,並且不能簡單地傳遞對外部物件的參考。您必須在建構函式的主體中包含一個表達式linkНаОбъемлющийКласс.super();。它將提供缺失的連結並且程式將編譯。

  3. 是否可以繼承匿名內部類別?

    透過描述匿名類,我們已經繼承了某個類別或實作了某個介面。extends或implements這些字不能直接應用於匿名類,但是沒有人打擾你提前準備並擴展所需的接口,我們將使用匿名類來實現該接口。下面程式碼中的範例。

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

    您不能從匿名類別繼承。

  4. 是否可以重寫內部類別?

    重寫內部類別就像它是外部類別的另一個方法一樣實際上沒有任何效果:

    //: 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();
      }
    }

    結論:

    New Egg()
    Egg.Yolk()

    預設建構函式由編譯器自動合成,並從基底類別呼叫預設建構函式。你可能認為創建物件時BigEgg應該使用「重寫」的類Yolk,但事實並非如此,從程式的結果可以看出。

    這個例子只是表明,當從外部類別繼承時,內部類別沒有什麼特殊的情況發生。兩個內部類別是完全獨立的實體,具有獨立的命名空間。換句話說,這是不可能的。

  5. 本地課程有哪些限制?

    首先,讓我們記住什麼是本地類別。這是一個用程式碼區塊描述的類,簡單來說就是 - 在引號之間{}。大多數情況下,這些引用是方法的主體。但它們也可以只是一個塊、靜態塊、if-s 體、循環等。

    本地類賦予了內部類別的特徵,但又具有鮮明的特點,即:

    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. Сколько у класса максимально может быть внутренних классов?

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

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