Как наследовать статические поля на разных языках ООП?

Короткий вопрос

Насколько я знаю, большинство языков ООП не позволяют наследовать статические поля. (C ++, Java, C #)
С другой стороны, ООП говорит, что не следует дублировать код.

  • Есть ли в языках ООП общий способ, который делает что-то вроде «наследования статических полей»?
  • Знаете ли вы более простой, уникальный для конкретного языка способ решения проблемы?
  • Существуют ли языки, в которых есть "встроенная"? (Я имею в виду как ключевое слово.)

(В любом случае, я знаю основное назначение статических полей, я просто хочу углубиться и избежать дублирования.)

Моя конкретная проблема

Я хочу создать фреймворк (C # или Java) и упростить его расширение. Поэтому я хочу, чтобы ограничения и информация о унаследованных классах как можно скорее поместили в базовый класс.

Я знаю, что каждый унаследованный класс должен иметь собственное статическое поле. (Я хочу создать счетчик объектов для каждого подкласса.)
Поэтому кажется логичным сделать что-то вроде «наследования статического поля» - где статическое поле необходимо для подклассов, а не для базового класса.
Я видел несколько хитрых решений (например: в C # использовались дженерики в C # наследование статических полей абстрактного класса), но я не могу поверить, что нет более простого способа.
Если нет более простого способа, объясните мне, как мне узнать об использовании дженериков?
Как мне смотреть на дженерики в контексте? Какие проблемы я должен с ними связать?
(В школе мы учили этому только «чтобы избежать дублирования кода», статическое отсоединение поля не акцентировалось! В этом контексте мне кажется, что дженерики являются классами и экземплярами одновременно, но я пока не нашел для этого понятного логического подхода.)


person PEZO    schedule 04.06.2013    source источник
comment
Я думаю, что CRTP может быть распространенным решением. Но не уверен, работает ли он на любом языке ООП.   -  person PEZO    schedule 04.06.2013


Ответы (3)


Вы пытаетесь использовать простой механизм (статические поля) для чего-то гораздо более сложного. Не делай этого. Похоже, вы зациклились на идее использования статических полей для хранения некоторой синглтон-подобной информации для каждого из ваших классов-потомков, при этом каким-то образом унифицируя доступ к нему, но это совершенно неправильный подход.

Забудьте о статических полях и создайте отдельный объект для хранения информации, необходимой для каждого класса. По сути, это может быть Dictionary<Type, Something> статическое поле или что-то более сложное. Во многом зависит от вашего варианта использования. Тогда вы увидите, что не будете повторяться и получите гораздо больше хороших функций.

Вам также следует прочитать что-нибудь о инверсии управления и Внедрение зависимостей. Возможно, то, что вы пытаетесь достичь, уже было успешно решено многими фреймворками IoC (такими как Ninject или Структурная карта и это лишь некоторые из них).

Дополнительное примечание: подумайте о поиске подходящей платформы, а не о создании собственной.

person Ondrej Tucny    schedule 04.06.2013
comment
Спасибо за предложение! К сожалению, я никогда не слышал о IoC. (Не могли бы вы сказать мне, где вы впервые узнали об этом?) - person PEZO; 05.06.2013
comment
Ну не помню. Я использую этот принцип много лет. - person Ondrej Tucny; 05.06.2013

@Pezo, вы неправильно понимаете как статические поля, так и универсальные.
Статические поля не наследуются, потому что они доступны без экземпляра, а использование концепции наследования применимо только к объектам, а не к классам.

Если у вас нет экземпляра класса, производного от данного базового класса, вы не можете использовать унаследованное [нестатическое] поле от этого базового класса. Но вы ВСЕГДА можете использовать статическое поле из ЛЮБОГО класса, независимо от того, есть ли у вас его экземпляр или нет, или экземпляр чего-либо еще в этом отношении. Они доступны для каждого экземпляра класса, а также доступны без какого-либо экземпляра какого-либо класса.

Что касается Generics, Generics и статические поля - это разные темы, у которых очень мало общего. Обобщения позволяют вам написать определение или шаблон для класса (или метода), не зависящего от типа, чтобы позже вы могли использовать его для создания реального конкретного класса, указав тип, который вы хотите использовать. Он может содержать статические и нестатические поля, свойства и методы так же, как и универсальный.

person Charles Bretana    schedule 04.06.2013
comment
Прошу прощения, если я был двусмысленен. Я в курсе того, что вы написали, поэтому использовал кавычки. Вопрос в следующем: как сделать какое-то поле, которое работает в подклассе как статическое поле, потому что я не хочу писать в каждом подклассе статическое поле. Думаю, это будет дублирование кода. - person PEZO; 04.06.2013
comment
В том-то и дело, что вам НЕ НУЖНО писать статическое поле в каком-либо другом классе. Он доступен везде, из любого кода, в любом классе или в любом экземпляре, без этого. Просто введите [ClassName].[FieldName]. Если вы продублируете статическое поле в другом классе, это будет второе, другое статическое поле в другом месте памяти с другим ценность. - person Charles Bretana; 04.06.2013
comment
Да, это то, что мне нужно: другое статическое поле, в другом месте памяти, с другим значением. Но я не хочу дублировать в каждом подклассе, потому что я могу сейчас заявить, что они мне понадобятся в подклассах. - person PEZO; 04.06.2013
comment
Вы хотите создать разные статические поля, по одному для каждого определенного класса, только с одним оператором ??? Тогда это НЕ одно и то же статическое поле, это разные статические поля, и вам нужно объявить каждое отдельно, с его собственным индивидуальным именем [namespace.ClassName.MemberName]. В противном случае, как, когда вы пытаетесь получить доступ к нему откуда-то в своем коде, компилятор узнает, какой из них вы хотите ???? - person Charles Bretana; 04.06.2013
comment
И даже тогда все они будут доступны, индивидуально и независимо, так же, как вы могли бы получить к ним доступ из класса, в котором они определены, или извне, с использованием одного и того же синтаксиса (namespace.className.MemberName), независимо от того, выполняется ли код. в экземпляре класса, в котором они объявлены, в подклассе, базовом классе или любом другом полностью несвязанном классе, который даже не является частью иерархии этого класса, даже если он находится в другой сборке. - person Charles Bretana; 04.06.2013
comment
Да, в основном я понимаю, что вы написали, и думаю так же. Как я уже сказал, я не хочу использовать реальные статические поля, мне нужно что-то, что имитирует как отдельное статическое поле в каждом подклассе. Пожалуйста, проверьте две ссылки, которые я нашел по этому поводу (одна в вопросе, а другая в качестве комментария), и я думаю, что это будет ясно. Я считаю, что это хорошее обычное ООП-решение проблемы, но меня интересует, есть ли другое или лучшее решение? - person PEZO; 04.06.2013
comment
@CharlesBretana: каждое из полей действительно является отдельным статическим полем, в другом месте памяти, с разным значением, но они НЕ независимы, так как они должны иметь одно и то же имя и автоматически присваиваться любому классу, который выбирает наследование от конкретного корневой класс, определяющий поле. - person C.B.; 26.09.2013
comment
@ C.B. если у них одно и то же имя, то это одно и то же поле. В противном случае, как компилятор мог узнать, что вы имеете в виду? Действительно, АвтоМагически !!! Это действительно было бы волшебством. Вы хотите, чтобы компилятор мог вернуться в прошлое и читать мысли разработчика, пишущего код? - person Charles Bretana; 07.01.2015

Есть ли общий способ в языках ООП, который делает что-то вроде «наследования статических полей»?

No.

person PEZO    schedule 21.06.2019