Какой метод в Java невозможно переопределить в классе-наследнике?

Ответ

В Java нельзя переопределить метод, объявленный с модификатором final. Попытка сделать это приведет к ошибке компиляции.

Почему используется final: Чтобы запретить изменение критичной логики в наследниках, гарантировать безопасность (например, в иммутабельных классах) или оптимизировать выполнение.

Пример ошибки переопределения final-метода:

class Parent {
    // Объявление final метода
    public final void displayId() {
        System.out.println("Parent ID: 100");
    }
}

class Child extends Parent {
    // ОШИБКА КОМПИЛЯЦИИ: Cannot override the final method from Parent
    @Override
    public void displayId() { 
        System.out.println("Child ID: 200");
    }
}

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

  • private методы: Не наследуются, поэтому в дочернем классе можно создать метод с такой же сигнатурой, но это будет новый, независимый метод, а не переопределение.
  • static методы: Связаны с классом, а не с экземпляром. Если в дочернем классе объявить статический метод с такой же сигнатурой, он скроет (hide) метод родителя, но не переопределит его. Вызов зависит от типа ссылки, а не от реального объекта.
class Parent {
    public static void staticMethod() { System.out.println("Parent static"); }
    private void privateMethod() { System.out.println("Parent private"); }
}

class Child extends Parent {
    // Это скрытие (hiding), а не переопределение.
    public static void staticMethod() { System.out.println("Child static"); }
    // Это совершенно новый метод, не связанный с Parent.privateMethod().
    private void privateMethod() { System.out.println("Child private"); }
}

Ответ 18+ 🔞

А, слушай, смотри, вот эта ваша Java, она такая хитрая жопа, блядь. Вот представь: ты написал метод и такой думаешь — «всё, идеально, пусть детишки мои его не трогают, а то опять какую-нибудь дичь наворочают». Так вот, для этого и придумали слово final, ёпта. Написал final перед методом — и всё, приехали. Наследники могут хоть обосраться, но переписать его не смогут. Попробуют — компилятор им сразу в ебучку: «Cannot override the final method from Parent», и сиди, мудак, исправляй.

Зачем это надо, спросишь? Да чтобы, блядь, критичную логику не сломали, чтобы в иммутабельных классах всё чётко было, или чтоб JVM могла пораскинуть мозгами и оптимизировать вызов. Короче, чтобы порядок был, а не бардак.

Вот смотри, как это выглядит, когда какой-то умник пытается:

class Parent {
    // Всё, приплыли, метод зафиналили
    public final void displayId() {
        System.out.println("Parent ID: 100");
    }
}

class Child extends Parent {
    // А тут наш гений пытается перебить папино
    @Override
    public void displayId() { // ОШИБКА! Ёбта, нельзя же!
        System.out.println("Child ID: 200");
    }
}

И всё, пиздец. Не скомпилируется, и правильно. Иди, блядь, думай, как по-другому свою хитрую жопу реализовать.

А теперь, внимание, блядь, тонкий момент! Есть два случая, где народ путается и думает, что переопределяет, а нихуя подобного:

  • private методы: Они же, сука, не наследуются вообще! Это как секрет в сейфе. Если в ребёнке написать метод с такой же сигнатурой — это будет просто совершенно новый, отдельный метод, ёпта. Никакого переопределения, просто совпадение, как хуй с горы.
  • static методы: Это вообще отдельная песня, блядь. Они привязаны к классу, а не к объекту. Если в наследнике объявить статик-метод с такой же сигнатурой — он просто спрячет (hide) родительский. А какой вызовется — зависит от того, через какую ссылку ты его зовёшь. Это не полиморфизм, это пиздец, мать его.
class Parent {
    public static void staticMethod() { System.out.println("Parent static"); }
    private void privateMethod() { System.out.println("Parent private"); }
}

class Child extends Parent {
    // Это не переопределение, а сокрытие! Hiding, блядь!
    public static void staticMethod() { System.out.println("Child static"); }
    // А это вообще новый private-метод, к родителю отношения не имеет.
    private void privateMethod() { System.out.println("Child private"); }
}

Вот и вся магия, блядь. final — это железобетонная стена. Хочешь переопределить? Иди нахуй, не получится. А private и static — это просто иллюзия, обманка для распиздяев. Запомни и не путай, а то потом будешь сидеть и ебать костыли, пока дебажишь.