JavaRush /Blog Java /Random-VI /Cấp độ 24. Trả lời các câu hỏi phỏng vấn về chủ đề cấp độ...
zor07
Mức độ
Санкт-Петербург

Cấp độ 24. Trả lời các câu hỏi phỏng vấn về chủ đề cấp độ

Xuất bản trong nhóm
Cấp độ 24. Trả lời câu hỏi phỏng vấn về chủ đề cấp độ - 1
  1. Các lớp bên trong ẩn danh biên dịch thành gì?

    Các lớp bên trong ẩn danh được biên dịch thành các tệp внешнийКласс$n.class. Theo đó, thay cho lớp bên ngoài là tên của lớp khung, trong đó lớp bên trong ẩn danh được mô tả. Ở chỗ n là một số từ 1 đến số lớp ẩn danh.

  2. Có thể kế thừa các lớp bên trong không?

    Có thể kế thừa các lớp bên trong từ những lớp khác.

    Việc kế thừa từ một lớp bên trong phức tạp hơn bình thường một chút, vì hàm tạo của lớp bên trong được liên kết với một tham chiếu đến đối tượng bên ngoài xung quanh. Vấn đề là tham chiếu đối tượng "ẩn" của lớp bên ngoài kèm theo phải được khởi tạo và không còn đối tượng bao quanh mặc định trong lớp dẫn xuất. Để chỉ ra rõ ràng đối tượng bên ngoài kèm theo, một cú pháp đặc biệt được sử dụng:

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

    Ở đây lớp InheritInnerchỉ mở rộng lớp bên trong chứ không mở rộng lớp bên ngoài. Nhưng khi nói đến việc tạo một hàm tạo, hàm tạo mặc định được cung cấp không phù hợp và bạn không thể đơn giản chuyển tham chiếu đến một đối tượng bên ngoài. Bạn phải bao gồm một biểu thức trong phần thân của hàm tạo linkНаОбъемлющийКласс.super();. Nó sẽ cung cấp liên kết còn thiếu và chương trình sẽ biên dịch.

  3. Có thể kế thừa các lớp bên trong ẩn danh không?

    Bằng cách mô tả một lớp ẩn danh, chúng ta đã kế thừa từ một số lớp hoặc triển khai một số giao diện. Các từ mở rộng hoặc triển khai không thể được áp dụng trực tiếp cho các lớp ẩn danh, nhưng không ai làm phiền bạn chuẩn bị trước và mở rộng giao diện cần thiết, mà chúng tôi sẽ triển khai bằng cách sử dụng một lớp ẩn danh. Một ví dụ trong mã dưới đây.

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

    Bạn không thể kế thừa từ một lớp ẩn danh.

  4. Có thể ghi đè các lớp bên trong không?

    Ghi đè lớp bên trong như thể nó là một phương thức khác của lớp bên ngoài thực sự không có tác dụng:

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

    Phần kết luận:

    New Egg()
    Egg.Yolk()

    Hàm tạo mặc định được trình biên dịch tự động tổng hợp và gọi hàm tạo mặc định từ lớp cơ sở. Bạn có thể nghĩ rằng khi tạo một đối tượng, BigEggnên sử dụng một lớp "được ghi đè" Yolk, nhưng điều này hoàn toàn không phải như vậy, như có thể thấy từ kết quả của chương trình.

    Ví dụ này chỉ đơn giản cho thấy rằng khi bạn kế thừa từ một lớp bên ngoài, không có gì đặc biệt xảy ra với các lớp bên trong. Hai lớp bên trong là các thực thể hoàn toàn riêng biệt, có các không gian tên độc lập. Nói cách khác, điều đó là không thể.

  5. Những hạn chế của các lớp học địa phương là gì?

    Đầu tiên, hãy nhớ lớp địa phương là gì. Đây là một lớp được mô tả trong một khối mã, nghĩa là, nói một cách đơn giản - giữa các dấu ngoặc kép {}. Thông thường, những trích dẫn này là phần nội dung của phương thức. Nhưng chúng cũng có thể chỉ là một khối, một khối tĩnh, một phần thân ifcủa -s, vòng lặp, v.v.

    Lớp cục bộ được ưu đãi với các tính năng của các lớp nội bộ, nhưng có các tính năng đặc biệt, cụ thể là:

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

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

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION