☕ Вопросы интервью по Java

Вопросы 101-110 для новичков и опытных разработчиков

Вопрос 101
Что такое полиморфизм?

Ответ: Полиморфизм (Polymorphism) - это концепция ООП, которая позволяет одному методу или объекту выполнять разные действия в зависимости от ситуации. Слово "полиморфизм" буквально означает "много форм".

Основные характеристики:
  • Позволяет одному методу иметь разные поведения
  • Достигается через переопределение методов (Method Overriding) и перегрузку методов (Method Overloading)
  • Делает код более гибким, переиспользуемым и легким в поддержке
Пример из жизни:

Человек может быть студентом в школе, клиентом в магазине и сыном/дочерью дома. Точно так же в Java один объект может вести себя по-разному в разных ситуациях.

Вопрос 102
Что такое runtime polymorphism (полиморфизм во время выполнения)?

Ответ: Runtime Polymorphism - это особенность, при которой метод, который будет выполняться, определяется во время выполнения программы (runtime) на основе фактического объекта, а не типа ссылки.

Ключевые моменты:
  • Достигается через переопределение методов (Method Overriding)
  • Позволяет ссылке на класс-родитель указывать на объект класса-потомка
  • Помогает реализовать гибкость и расширяемость приложений
Пример:

Если ссылка Animal указывает на объект Dog, вызов метода sound() выполнит версию метода из класса Dog, а не Animal.


Animal animal = new Dog();  // Ссылка на Dog сохранена в переменной Animal
animal.sound();  // Вызывает метод Dog.sound(), а не Animal.sound()
                
Вопрос 103
Что такое переопределение методов (Method Overriding)?

Ответ: Method Overriding - это особенность, при которой класс-потомок предоставляет свою собственную реализацию метода, который уже определен в классе-родителе. Это позволяет классу-потомку изменять или расширять поведение наследованного метода.

Требования для переопределения:
  • Требуется наследование между классом-родителем и классом-потомком
  • Метод в обоих классах должен иметь одно имя, одинаковые параметры и одинаковый тип возвращаемого значения
  • Используется для достижения Runtime Polymorphism в Java
Пример:

class Animal {
    void sound() {
        System.out.println("Some sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Bark");  // Переопределенный метод
    }
}
                
Вопрос 104
Что такое перегрузка методов (Method Overloading)?

Ответ: Method Overloading - это особенность Java, которая позволяет иметь несколько методов с одинаковым именем в одном классе, но с разными списками параметров. Это позволяет методу выполнять похожие задачи с разными входными данными.

Правила перегрузки:
  • Методы должны отличаться количеством параметров
  • Методы должны отличаться типом параметров
  • Методы должны отличаться порядком параметров
  • Улучшает читаемость и переиспользуемость кода
  • Используется для достижения Compile-Time Polymorphism
Пример:

class Calculator {
    // Перегрузка 1: два int параметра
    int add(int a, int b) {
        return a + b;
    }
    
    // Перегрузка 2: два double параметра
    double add(double a, double b) {
        return a + b;
    }
    
    // Перегрузка 3: три int параметра
    int add(int a, int b, int c) {
        return a + b + c;
    }
}
                
Вопрос 105
Можно ли переопределить static метод?

Ответ: Нет, нельзя переопределить static метод в Java. Static методы принадлежат классу, а не объекту, поэтому их нельзя переопределить.

Почему нельзя переопределить static методы:
  • Static методы разрешаются во время компиляции (compile-time), а не во время выполнения
  • Static методы принадлежат классу, а не экземпляру
  • Если вы объявите static метод с одинаковым именем в подклассе, это будет скрытие методов (method hiding), а не переопределение

class Parent {
    static void display() {
        System.out.println("Parent static method");
    }
}

class Child extends Parent {
    static void display() {  // Это скрытие метода (method hiding), не переопределение
        System.out.println("Child static method");
    }
}
                
Вопрос 106
Можно ли переопределить перегруженный метод?

Ответ: Да, можно переопределить перегруженный метод. С точки зрения компилятора, перегруженный метод - это совершенно другой метод. Переопределение - это совсем другое, и решение о том, какой метод вызывать, откладывается до runtime.

Основные моменты:
  • Перегрузка (Overloading) - это Compile-Time Polymorphism
  • Переопределение (Overriding) - это Runtime Polymorphism
  • Они работают независимо друг от друга
Пример:

class Parent {
    void display(int a) {
        System.out.println("Parent: " + a);
    }
}

class Child extends Parent {
    @Override
    void display(int a) {  // Переопределение
        System.out.println("Child: " + a);
    }
    
    void display(String a) {  // Перегрузка
        System.out.println("Child String: " + a);
    }
}
                
Вопрос 107
Можно ли перегрузить main() метод?

Ответ: Да, в Java можно перегрузить main метод. Вы можете создать несколько main методов с разными сигнатурами. Но JVM всегда ищет main метод с сигнатурой public static void main(String[] args), поэтому это будет точкой входа программы.

Пример перегрузки main():

public class Main {
    // Основной main - точка входа JVM
    public static void main(String[] args) {
        System.out.println("Main method called");
        main(5);  // Вызов перегруженного main
        main("Hello");  // Вызов перегруженного main
    }
    
    // Перегрузка 1: с int параметром
    public static void main(int a) {
        System.out.println("Main with int: " + a);
    }
    
    // Перегрузка 2: с String параметром
    public static void main(String str) {
        System.out.println("Main with String: " + str);
    }
}
                
Вывод:

Main method called
Main with int: 5
Main with String: Hello
                
Вопрос 108
Что такое Method Overloading и Method Overriding?

Ответ: Это две разные концепции полиморфизма в Java:

Method Overloading (Compile-Time Polymorphism):

Два или более методов в одном классе имеют одинаковое имя, но разные сигнатуры параметров.


class Calculator {
    int multiply(int a, int b) { 
        return a * b; 
    }
    
    int multiply(int a, int b, int c) {
        return a * b * c;
    }
}
                
Method Overriding (Runtime Polymorphism):

Подкласс предоставляет свою собственную реализацию метода, который уже определен в суперклассе, с одинаковой сигнатурой и типом возврата.


class Vehicle {
    void drive() {
        System.out.println("Driving a vehicle");
    }
}

class Car extends Vehicle {
    @Override
    void drive() {
        System.out.println("Driving a car");
    }
}
                
Вопрос 109
Можно ли переопределить private методы?

Ответ: Нет, private методы нельзя переопределить в Java, потому что они доступны только внутри класса, в котором они объявлены. Поскольку подклассы не могут получить доступ к private методам, они не могут предоставить реализацию переопределения.

Ключевые моменты:
  • Private методы не наследуются подклассами
  • Метод с одинаковым именем в подклассе рассматривается как новый метод, а не переопределение
  • Переопределение методов требует, чтобы метод был виден подклассу

class Parent {
    private void display() {  // Private метод
        System.out.println("Parent private method");
    }
}

class Child extends Parent {
    private void display() {  // Это НОВЫЙ метод, не переопределение
        System.out.println("Child private method");
    }
}
                
Вопрос 110
Можно ли изменить область видимости переопределенного метода в подклассе?

Ответ: Да, подкласс может увеличить видимость переопределенного метода, но не может уменьшить её. Java не позволяет переопределенному методу иметь более ограничивающий модификатор доступа, чем метод в суперклассе.

Правила видимости:
  • Видимость может быть расширена (например, protected -> public)
  • Видимость не может быть сужена (например, public -> protected или private)
  • Это правило гарантирует, что переопределенный метод остается доступным везде, где был доступен метод в суперклассе
Примеры:

// ✅ Правильно: Расширение видимости
class Parent {
    protected void display() {
        System.out.println("Parent protected method");
    }
}

class Child extends Parent {
    @Override
    public void display() {  // ✅ Правильно: protected -> public
        System.out.println("Child public method");
    }
}

// ❌ Неправильно: Сужение видимости
class Parent2 {
    public void show() {
        System.out.println("Parent public method");
    }
}

class Child2 extends Parent2 {
    @Override
    protected void show() {  // ❌ Компилятор выдаст ошибку
        System.out.println("Child protected method");
    }
}
                
Правила порядка видимости (от наименее к наиболее видимой):

private < package-private < protected < public