Наследование атрибутов

Наследование атрибутов

    Наследование свойств и атрибутов в C#

    Есть класс SuperClassBase , в котором определено свойство SuperProperty . К этому свойству применены атрибуты, например, [Browsable(false)] . Как сделать так, чтобы наследники этого класса могли переопределять значение атрибута для этого свойства? Можно ли обойтись без определения свойства виртуальным и перекрытия его в наследнике с применением атрибута с другим значением?

    Судя по всему, единственный способ переопределить атрибуты — это именно перекрыть соответствующее свойство в наследнике.

    Наследование атрибутов в python с использованием __init__

    Я человек Java, который только начал изучать Python. Возьмите этот пример:

    Я уверен, что есть много избыточного кода (я знаю на Java, есть много избыточности для бит кода выше).

    Какие части являются избыточными, по отношению к которым атрибуты уже унаследованы от родительского класса?

    При написании функции __init__ для класса в python вы всегда должны вызывать функцию __init__ своего суперкласса. Мы можем использовать это для передачи соответствующих атрибутов непосредственно в суперкласс, поэтому ваш код будет выглядеть так:

    Как указывали другие, вы можете заменить строку

    и код будет делать то же самое. Это связано с тем, что в python instance.method(args) просто сокращается Class.method(instance, args) . Если вы хотите использовать super , вам нужно убедиться, что вы указываете object в качестве базового класса для Person , как это было в моем коде.

    документация python содержит дополнительную информацию о том, как использовать ключевое слово super . Важным в этом случае является то, что он говорит python искать метод __init__ в суперклассе self , который не является Teenager

    Чуть более чистый способ мне нравится:

    В этом случае это не имеет большого значения, но когда у вас есть __init__ с множеством аргументов, это облегчает жизнь.

    Атрибуты в Python не наследуются, когда они определены в конструкторе, а конструктор родительского класса не вызывается, если вы не выполните все его вручную:

    __init__ , в отличие от конструктора java, автоматически не вызывается для каждого класса в иерархии наследования — вам нужно сделать это самостоятельно.

    Кроме того, все ваши иерархии объектов должны внедряться в object (за исключением особых случаев).

    Ваш код должен читать:

    super создает делегат для своего второго аргумента ( self ), который вызывает следующую функцию в списке функций для вызова каждого имени ( «порядок разрешения метода» ). Это не совсем то же самое, что вызывать метод суперкласса, как это происходит в Java.

    Вы также можете написать super(type(self), self).__init__(name, phone) , но если вы наследуете дальше от этого класса, type(self) может быть не Teenager , и вы можете иметь бесконечную рекурсию. Это одно практическое следствие того, что вы работаете с объектом делегата с разницей MRO, а не напрямую вызываете конструктор суперкласса.

    Наследование и атрибут Description

    Здравствуйте, подскажите пожалуйста, можно ли как то настроить интерфейс (наследовать его от какого то другого), так чтобы наследуемые от него классы обязательно должны будут иметь такой атрибут [Description(«Описание свойства»)] на всех своих свойствах?

    Вопрос2: Обязательно в наследуемом классе должны быть заново прописаны все свойства которые есть в интерфейсе, или при наследовании они наследуются (сорри за тафталогию)?

    Добавлено через 8 минут
    Не очень хочется каждый раз копипастить все свойства из интерфейса при его реализации

    [Category, Description] для нового компонента
    Люди исправьте пожалуйста код, а то я взял пример из одной книжки для новичков.

    Наследование интерфейса и наследование реализации
    Начал читать книгу GoF и сразу же в предисловии попал в тупик. Чем отличается.

    Наследование С# , наследование полей
    В классе есть приватное ПОЛЕ . Мне нужно использовать его в классе потомке .

    т.е. другого выхода нет, так понимаю

    Добавлено через 1 минуту
    Usaga,

    Alex_trader, тем, что свойства базового класса будут общие для всех наследников. Общие и с атрибутами.

    Добавлено через 1 минуту
    А абстрактность добавит «интерфейсности».

    Alex_trader, ну вот и разматывай всю иерархию наследования пока не наткнёшься на нужный атрибут или пока не закончатся родительские классы. Это будет самопальный вариант наследования атрибутов классами.

    Добавлено через 6 минут
    Alex_trader, при наследовании от класса (а не при реализации интерфейса) атрибуты наследуются:

    Программирование на Python: Часть 6. Классы

    Этот контент является частью # из серии # статей:

    Этот контент является частью серии:

    Следите за выходом новых статей этой серии.

    Мы переходим к одной из самых интересных тем цикла — объектно-ориентированному программированию (ООП) в Python. С точки зрения ООП, класс представляет собой коллекцию данных. Использование классов дает нам прежде всего преимущества абстрактного подхода в программировании.

    1. Полиморфизм: в разных объектах одна и та же операция может выполнять различные функции. Слово «полиморфизм» имеет греческую природу и означает «имеющий многие формы». Простым примером полиморфизма может служить функция count() , выполняющая одинаковое действие для различных типов обьектов: ‘abc’.count(‘a’) и [1, 2, ‘a’].count(‘a’) . Оператор плюс полиморфичен при сложении чисел и при сложении строк.
    2. Инкапсуляция: можно скрыть ненужные внутренние подробности работы объекта от окружающего мира. Это второй основной принцип абстракции. Он основан на использовании атрибутов внутри класса. Атрибуты могут иметь различные состояния в промежутках между вызовами методов класса, вследствие чего сам объект данного класса также получает различные состояния — state.
    3. Наследование: можно создавать специализированные классы на основе базовых. Это позволяет нам избегать написания повторного кода.
    4. Композиция: объект может быть составным и включать в себя другие объекты.

    Объектно-ориентированный подход в программировании подразумевает следующий алгоритм действий.

    1. Описывается проблема с помощью обычного языка с использованием понятий, действий, прилагательных.
    2. На основе понятий формулируются классы.
    3. На основе действий проектируются методы.
    4. Реализуются методы и атрибуты.

    Мы получили скелет — объектную модель. На основе этой модели реализуется наследование. Для проверки модели:

    1. пишется так называемый use cases — сценарий возможного поведения модели, где проверяется вся функциональность;
    2. функционал при этом может быть исправлен либо добавлен.

    Объектно-ориентированный подход хорош там, где проект подразумевает долгосрочное развитие, состоит из большого количества библиотек и внутренних связей.

    Механизм классов языка Python представляет собой смесь механизмов классов C++ и Modula-3. Наиболее важные особенности классов в питоне:

    1. множественное наследование;
    2. производный класс может переопределить любые методы базовых классов;
    3. в любом месте можно вызвать метод с тем же именем базового класса;
    4. все атрибуты класса в питоне по умолчанию являются public, т.е. доступны отовсюду; все методы — виртуальные, т.е. перегружают базовые.

    Сегодня мы рассмотрим следующие аспекты объектно-ориентированного программирования.

    1. Что такое класс.
    2. Атрибуты класса.
    3. self.
    4. Наследование.
    5. ООП в действии: пример создания классов.

    1. Что такое класс

    Класс — это пользовательский тип. Простейшая модель определения класса выглядит следующим образом:

    Каждая такая запись генерирует свой объект класса. Отличие от C++ в том, что в плюсах описание класса — это лишь объявление, а в питоне — это создание объекта. Есть также другой тип объекта — инстанс класса, который генерируется при вызове:

    Объект класса и инстанс класса — это два разных объекта. Первый генерируется на этапе объявления класса, второй — при вызове имени класса. Объект класса может быть один, инстансов класса может быть сколько угодно.

    Инструкция — это, как правило, определение функции. При определении класса создается новое пространство имен и создается объект-класс, который является оболочкой для всех инструкций.

    Объекты классов поддерживают два вида операций:

    • доступ к атрибутам;
    • создание экземпляра класса.

    2. Атрибуты класса

    Атрибуты класса бывают двух видов:

    Атрибуты данных обычно записываются сверху. Память для атрибутов выделяется в момент их первого присваивания — либо снаружи, либо внутри метода. Методы начинаются со служебного слова def.

    Доступ к атрибутам выполняется по схеме obj.attrname.

    Здесь Simple.var и Simple.f — пользовательские атрибуты. Есть также стандартные атрибуты:

    Создание экземпляра класса похоже на то, как будто мы делаем вызов функций:

    Будет создан пустой объект smpl. Если мы хотим, чтобы при создании выполнялись какие-то действия, нужно определить конструктор, который будет вызываться автоматически:

    При создании объекта smpl будет создан пустой список list. Конструктору можно передать аргументы:

    Атрибут данных можно сделать приватным (private) — т.е. недоступным снаружи — для этого слева нужно поставить два символа подчеркивания:

    Последняя строка вызовет исключение — атрибут __private_attr годен только для внутреннего использования.

    Методы необязательно определять внутри тела класса:

    Пустой класс можно использовать в качестве заготовки для структуры данных:

    Обычно первый аргумент в имени метода — self. Как говорит автор языка Гвидо Ван Россум, это не более чем соглашение: имя self не имеет абсолютно никакого специального значения.

    self полезен для того, чтобы обращаться к другим атрибутам класса:

    Self — это аналог «this» в C++.

    Определение производного класса выглядит следующим образом:

    Если базовый класс определен не в текущем модуле:

    Разрешение имен атрибутов работает сверху вниз: если атрибут не найден в текущем классе, поиск продолжается в базовом классе, и так далее по рекурсии. Производные классы могут переопределить методы базовых классов — все методы являются в этом смысле виртуальными. Вызвать метод базового класса можно с префиксом:

    В питоне существует ограниченная поддержка множественного наследования:

    Поиск атрибута производится в следующем порядке:

    1. в Derived;
    2. в Base1, затем рекурсивно в базовых классах Base1;
    3. в Base2, затем рекурсивно в базовых классах Base2
    4. и т.д.

    Создадим два класса: Person — хранит общую информацию о людях — имя, профессия, зарплата; класс Manager — специализированный производный класс. В классе Person мы создадим свою версию для стандартной встроенной функции str, которая есть по умолчанию в любом питоновском классе — для этого она будет иметь префикс с двумя символами подчеркивания слева и справа. Когда мы попытаемся распечатать инстанс класса, будет вызвана __str__.

    Создаем первый инстанс класса Person:

    Создаем второй инстанс класса Person:

    Вызываем перегруженную функцию __str__;

    Создаем инстанс класса Manager:

    Основные свойства ООП — полиморфизм, наследование, инкапсуляция. Класс — это пользовательский тип, состоящий из методов и атрибутов. Инстанс класса создается путем вызова имени класса как функции с параметрами. Объект состоит из атрибутов и методов. Атрибут — это переменная, метод — это функция. Отличия метода от функции в том, что у него есть первый параметр — self. Полиморфизм позволяет нам работать с различными типами объектов так, что нам не нужно задумываться о том, к какому типу они принадлежат. Объекты могут скрывать (инкапсулировать) свое внутреннее состояние. Это достигается за счет того, что доступ к атрибутам осуществляется не напрямую, а через методы. Класс может быть производным от одного или нескольких классов. Производный класс наследует все методы базового класса. Базовых классов может быть несколько. Объектный дизайн должен быть прозрачным, понятным и описан, что называется, в ‘терминах человеческого языка’.

    В следующей статье мы расскажем о работе со специальными методами и атрибутами классов. Код примеров проверялся на версии питона 2.6.

    Наследование атрибутов в инфо-типе 1222

    Давеча занесло меня опять в настройки инфо-типа 1222. Даже не столько в настройки, сколько в поиск ответа на вопрос, каким образом работает наследование атрибутов в инфо-типе 1222? И работает ли вообще Если интересно, предлагаю потратить пару минут.

    1. Суть проблемы

    Рассмотрим ситуацию, в которой возник вопрос.

    На объекте «Организационная единица» (O) создается атрибут, для которого в настройках активирован механизм наследования (см. кластер T77OMATTR).

    Рисунок 1. Создание атрибута для организационной единицы

    N.B. Работа с инфо-типом 1222 должна осуществляться с помощью транзакции PPOMA. См. заметку Ведение инфо-типа 1222

    Заведенное значение на родительском элементе наследовалось на подчиненные

    Рисунок 2. Наследование атрибута на подчиненные элементы

    Затем на «родительском» элементе, посредством ручек пользователей или консультанта, создается сплит записи инфо-типа 1222. Например, изменилось значение атрибута с какой-либо даты:

    Рисунок 3. Создание сплита для атрибута на родительском элементе

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

    Рисунок 4.

    На представленном примере видно, что на подчиненную организационную единицу унаследовано первоначальное значение атрибута. Сплит, который можно наблюдать на родительском объекте (см. Рисунок #3), отсутствует на подчиненном .

    Теперь изменим Период анализа, например, с той даты, на которую было заведено новое значение атрибута на «родительском» элементе

    Рисунок 5.

    Наследованное значение атрибута на подчиненном элементе было изменено, согласно запрошенному периоду анализа.

    2. А проблема ли это?

    Согласно SAP ноте 1792251 — Inheritance and splits in infotype 1222, описанная ситуация не является ошибкой.

    When a split exists in infotype 1222 of a parent organizational unit, with different values of an attribute with inheritance, you observe that this same split is not replicated into each of the child objects, therefore you think that the attribute value might not be correctly determined and inherited in the child objects

    The reason for this behavior is that no split data will be saved into the corresponding child objects for an inherited attribute. This is no problem because the system will be able to retrieve the attribute value correctly anytime, and dynamically, according to the preview period on top of PPOMA* transactions.

    The system behaves as expected. If there are splits in the parent organizational unit with different data, you will obtain the correct attribute value corresponding to the preview period of PPOMA* transactions. If the attribute changes its value in the past, or future, you will be able to see this information when the preview period covers this time….

    Да, и в «ноте» тоже рассматривается пример данной ситуации.

    Наследование – важная составляющая объектно-ориентированного программирования. Так или иначе мы уже сталкивались с ним, ведь объекты наследуют атрибуты своих классов. Однако обычно под наследованием в ООП понимается наличие классов и подклассов. Также их называют супер- или надклассами и классами, а также родительскими и дочерними классами.

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

    Простое наследование методов родительского класса

    В качестве примера рассмотрим разработку класса столов и его двух подклассов – кухонных и письменных столов. Все столы, независимо от своего типа, имеют длину, ширину и высоту. Пусть для письменных столов важна площадь поверхности, а для кухонных – количество посадочных мест. Общее вынесем в класс, частное – в подклассы.

    Связь между родительским и дочерним классом устанавливается через дочерний: родительские классы перечисляются в скобках после его имени.

    В данном случае классы KitchenTable и DeskTable не имеют своих собственных конструкторов, поэтому наследуют его от родительского класса. При создании экземпляров этих столов, передавать аргументы для __init__() обязательно, иначе возникнет ошибка:

    Несомненно можно создавать столы и от родительского класса Table. Однако он не будет, согласно неким родственным связям, иметь доступ к методам setPlaces() и square(). Точно также как объект класса KitchenTable не имеет доступа к единоличным атрибутам сестринского класса DeskTable.

    В этом смысле терминология «родительский и дочерний класс» не совсем верна. Наследование в ООП – это скорее аналог систематизации и классификации наподобие той, что есть в живой природе. Все млекопитающие имеют четырехкамерное сердце, но только носороги – рог.

    Полное переопределение метода надкласса

    Что если в подклассе нам не подходит код метода его надкласса. Допустим, мы вводим еще один класс столов, который является дочерним по отношению к DeskTable. Пусть это будут компьютерные столы, при вычислении рабочей поверхности которых надо отнимать заданную величину. Имеет смысл внести в этот новый подкласс его собственный метод square():

    При создании объекта типа ComputerTable по-прежнему требуется указывать параметры, так как интерпретатор в поисках конструктора пойдет по дереву наследования сначала в родителя, а потом в прародителя и найдет там метод __init__().

    Однако когда будет вызываться метод square(), то поскольку он будет обнаружен в самом ComputerTable, то метод square() из DeskTable останется невидимым, т. е. для объектов класса ComputerTable он окажется переопределенным.

    Дополнение, оно же расширение, метода

    Если посмотреть на вычисление площади, то часть кода надкласса дублируется в подклассе. Этого можно избежать, если вызвать родительский метод, а потом дополнить его:

    Здесь вызывается метод другого класса, а потом дополняется своими выражениями. В данном случае вычитанием.

    Рассмотрим другой пример. Допустим, в классе KitchenTable нам не нужен метод, поле places должно устанавливаться при создании объекта в конструкторе. В классе можно создать собсвенный конструктор с чистого листа, чем переопределить родительский:

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

    Теперь при создании объекта типа KitchenTable надо указывать в конструкторе четыре аргумента. Три из них будут переданы выше по лестнице наследования, а четвертый оприходован на месте.

    Практическая работа

    Разработайте программу по следующему описанию.

    В некой игре-стратегии есть солдаты и герои. У всех есть свойство, содержащее уникальный номер объекта, и свойство, в котором хранится принадлежность команде. У солдат есть метод «иду за героем», который в качестве аргумента принимает объект типа «герой». У героев есть метод увеличения собственного уровня.

    В основной ветке программы создается по одному герою для каждой команды. В цикле генерируются объекты-солдаты. Их принадлежность команде определяется случайно. Солдаты разных команд добавляются в разные списки.

    Измеряется длина списков солдат противоборствующих команд и выводится на экран. У героя, принадлежащего команде с более длинным списком, поднимается уровень.

    Отправьте одного из солдат первого героя следовать за ним. Выведите на экран идентификационные номера этих двух юнитов.

    Курс с примерами решений практических работ: android-приложение, pdf-версия.

    2.4.2. Наследование атрибутов

    Как упоминалось выше, сущность в подклассе представляет тот же объект реального мира, что и ее суперкласс, и может обладать атрибутами, как связанными с суперклассом, так и специфическими для данного подкласса.

    Например, подкласс Торговый_агент обладает всеми атрибутами суперкласса Сотрудник (т.е. атрибутами Код_сотрудника, ФИО, Адрес и Дата_рождения), а также специфическими атрибутами подкласса Торговый_агент (т.е. атрибутами Подорожные и Торговый_зал).

    Сущность, ее подклассы, подклассы данных подклассов и так далее — все это называется иерархией типа (type hierarchy). Иерархии типов могут иметь разные названия: иерархия специализации (specialization hierarchy) — например, подкласс Управляющий является специализацией суперкласса Сотрудник; иерархия генерализации (generalization hierarchy) — например, суперкласс Сотрудник является генерализацией подкласса Управляющий; иерархия принадлежности (IS-A hierarchy) — например, менеджер (подкласс Управляющий) является сотрудником (принадлежит суперклассу Сотрудник). В следующих разделах процессы специализации и генерализации описываются более подробно.

    2.4.3. Специализация

    Процесс увеличения различий между отдельными членами множества сущности за счет выделения их отличительных характеристик называется специализацией.

    Рассмотрим, например, процедуру специализации, в которой идентифицируется множество подклассов суперкласса Сотрудник, включая подклассы Управляющий, Секретарь и Торговый_агент. Ее можно представить схематически — в виде EER-диаграммы, показанной на Рис.2.4.1.

    Рис. 2.4.1. Специализация сущности Сотрудник no подклассам на основе служебных ролей

    Обратите внимание, что суперкласс Сотрудник и его подклассы, которые также являются множествами сущностей, здесь обозначены прямоугольниками. Подклассы специализации соединяются линиями с кружком, который, в свою очередь, соединяется с суперклассом. Символ принадлежности множеству (Ì) на каждой линии, соединяющей подкласс с кружком, указывает направление связи «Подкласс/суперкласс» (например, Управляющий Ì Сотрудник). Символ «о» в кружке специализации обозначает накладываемое на связь «подкласс/суперкласс» ограничение, которое более подробно описывается ниже, в разделе 2.4.5.

    Атрибуты Подорожные и Район_продаж связаны только с подклассом Торговый_агент, a это означает, что они не могут быть применены к подклассу Управляющий или Секретарь.

    2.4.4. Генерализация

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

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

    2.4.5. Ограничения, накладываемые на процедуры специализации и генерализации

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

    Первое ограничение называется ограничением непересечения (disjoint constraint). Оно гласит, что если подклассы некоторой специализации не пересекаются, то каждая отдельная сущность может быть членом только одного из подклассов данной специализации.

    Если подклассы специализации пересекаются, в таком случае сущность может быть членом сразу нескольких подклассов специализации. Для представления пересекающейся (nondisjoint) специализации используется символ «о», который располагается в центре кружка, соединяющего подклассы данного суперкласса. Для нашего примера это означает, что сотрудник может быть одновременно и менеджером (членом Управляющий), и торговым агентом (т.е. членом Торговый_агент).

    Второе ограничение специализации называется ограничением участия (participation constraint), оно может быть полным или частичным. Специализация с полным участием означает, что каждая сущность суперкласса должна быть членом подкласса этой специализации.

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

    Специализация с частичным участием означает, что сущность не обязательно должна быть членом любого подкласса этой специализации. Для обозначения частичного участия между суперклассом и кружком специализации проводят одинарную линию.

    Читайте так же:  Виновник дтп пьян страховка выплатить