В статических методах нет объекта, обеспечивающего надлежащее управление механизмом переопределения.
Обычный механизм виртуальных методов класса / экземпляра позволяет точно настроить управление переопределениями следующим образом: каждый реальный объект является экземпляром ровно одного класса. Этот класс определяет поведение переопределений; он всегда получает первую трещину в виртуальных методах. Затем он может выбрать вызов родительского метода в нужное время для его реализации. Каждый родительский метод также получает свою очередь для вызова своего родительского метода. Это приводит к хорошему каскаду родительских вызовов, который реализует одно из понятий повторного использования кода, которым известна объектная ориентация. (Здесь код базовых / суперклассов повторно используется относительно сложным способом; другое ортогональное понятие повторного использования кода в ООП - это просто наличие нескольких объектов одного и того же класса.)
Базовые классы могут повторно использоваться различными подклассами, и каждый может комфортно сосуществовать. Каждый класс, который используется для создания экземпляров объектов, диктует свое поведение, мирно и одновременно сосуществуя с другими. Клиент может контролировать, какое поведение он хочет и когда, выбирая, какой класс использовать для создания экземпляра объекта и передачи другим по желанию.
(Это не идеальный механизм, так как всегда можно определить возможности, которые не поддерживаются, конечно, поэтому шаблоны, такие как фабричный метод и внедрение зависимостей, размещены сверху.)
Таким образом, если бы мы сделали возможность переопределения для статики без изменения чего-либо еще, у нас были бы трудности с упорядочением переопределений. Было бы трудно определить ограниченный контекст для применимости переопределения, поэтому вы получите переопределение глобально, а не локально, как с объектами. Не существует экземпляра объекта для переключения поведения. Итак, если кто-то вызвал статический метод, который, как оказалось, был переопределен другим классом, переопределение получит контроль или нет? Если есть несколько таких переопределений, кто получает контроль первым? второй? С переопределением объекта экземпляра у всех этих вопросов есть значимые и аргументированные ответы, но со статикой они не имеют.
Переопределения для статики были бы в значительной степени хаотичными, и подобные вещи делались раньше.
Например, в Mac OS System 7 и более ранних версиях использовался механизм исправления ловушек для расширения системы путем получения контроля над системными вызовами приложений перед операционной системой. Вы можете думать о таблице исправлений системного вызова как о массиве указателей на функции, во многом как vtable для объектов экземпляров, за исключением того, что это была одна глобальная таблица.
Это вызвало невыразимое горе для программистов из-за неупорядоченного характера исправления ловушек. Тот, кто в последний раз исправлял ловушку, в основном выиграл, даже если не хотел. Каждый патч ловушки будет захватывать предыдущее значение ловушки для своего рода возможности родительского вызова, которая была чрезвычайно хрупкой. Удаляя патч-ловушку, скажем, когда вам больше не нужно было знать, что системный вызов считается дурным тоном, поскольку у вас не было информации, необходимой для удаления вашего патча (если вы сделали это, вы также удалили бы все остальные патчи, которые следовали вы).
Это не означает, что было бы невозможно создать механизм для переопределений статики, но я бы предпочел вместо этого превратить статические поля и статические методы в поля экземпляров и методы экземпляров метаклассов, чтобы обычный объект затем будут применяться методы ориентации. Обратите внимание, что существуют системы, которые делают это также: CSE 341: классы Smalltalk и метаклассы ; Смотрите также: Что такое Smalltalk-эквивалент статики Java?
Я пытаюсь сказать, что вам нужно сделать серьезный языковой дизайн, чтобы он работал даже достаточно хорошо. Для одного примера был сделан наивный подход, который хромал, но был очень проблематичным и, возможно, (то есть, я бы поспорил) архитектурным недостатком, предоставив неполную и сложную в использовании абстракцию.
К тому времени, когда вы закончите разработку функции статических переопределений для правильной работы, вы, возможно, только что изобрели некоторую форму метаклассов, которая является естественным расширением ООП в / для основанных на классах методов. Таким образом, нет никаких причин не делать этого - и некоторые языки на самом деле делают. Возможно, это всего лишь более ограниченное требование, которое многие языки предпочитают не выполнять.
self
указатель, который указывает на класс, а не на экземпляр класса.