Черта (компьютерное программирование)
Эта статья может быть слишком технической для понимания большинства читателей . ( Март 2012 г. ) |
Эта статья нуждается в дополнительных цитатах для проверки . ( ноябрь 2022 г. ) |
В компьютерном программировании черта языковая — это концепция , представляющая собой набор методов , которые можно использовать для расширения функциональности класса . [1] [2]
Обоснование
[ редактировать ]В объектно-ориентированном программировании поведение иногда разделяется между классами, которые не связаны друг с другом. Например, многие несвязанные классы могут иметь методы для сериализации объектов в JSON . Исторически сложилось так, что существовало несколько подходов к решению этой проблемы без дублирования кода в каждом классе, которому требовалось такое поведение. Другие подходы включают множественное наследование и миксины , но у них есть недостатки: поведение кода может неожиданно измениться, если изменить порядок применения миксинов или если к родительским классам или миксинам добавляются новые методы.
Черты решают эти проблемы, позволяя классам использовать эту черту и получать желаемое поведение. Если класс использует более одного признака, порядок использования этих признаков не имеет значения. Методы, предоставляемые типажами, имеют прямой доступ к данным класса.
Характеристики
[ редактировать ]Трейты объединяют аспекты протоколов (интерфейсов) и миксинов . Как и интерфейс, черта определяет одну или несколько сигнатур методов , реализации которых должны обеспечивать реализующие классы. Как и примесь, черта обеспечивает дополнительное поведение реализующего класса.
В случае конфликта имен между методами, предоставляемыми разными характеристиками, программист должен явно устранить неоднозначность, какой из этих методов будет использоваться в классе; тем самым вручную решая алмазную проблему множественного наследования . Это отличается от других методов композиции в объектно-ориентированном программировании, где конфликтующие имена автоматически разрешаются правилами области видимости .
Операции, которые можно выполнять с признаками, включают: [3] [4]
- симметричная сумма : операция, которая объединяет два непересекающихся признака для создания нового признака.
- переопределение (или асимметричная сумма ): операция, которая формирует новый признак путем добавления методов к существующему признаку, возможно, переопределяя некоторые из его методов.
- псевдоним : операция, которая создает новый признак путем добавления нового имени к существующему методу.
- исключение : операция, которая формирует новый признак путем удаления метода из существующего признака. (Объединение этого с операцией псевдонима дает неглубокую операцию переименования ).
Если метод исключен из признака, этот метод должен быть предоставлен классом, который использует этот признак, или родительским классом этого класса. Это связано с тем, что методы, предоставляемые этим признаком, могут вызывать исключенный метод.
Состав признаков является коммутативным данных признаков A и B (т.е. для A + B эквивалентно B + A ) и ассоциативным (т. е. для данных признаков A , B и C ( A + B ) + C эквивалентно A + ( B + С )). [1]
Ограничения
[ редактировать ]Хотя черты предлагают значительные преимущества перед многими альтернативами, у них есть свои ограничения.
Требуемые методы
[ редактировать ]Если признак требует, чтобы класс-потребитель предоставил определенные методы, признак не может знать, являются ли эти методы семантически эквивалентными потребностям признака. Для некоторых динамических языков, таких как Perl, требуемый метод можно идентифицировать только по имени метода, а не по полной сигнатуре метода , что затрудняет гарантию соответствия требуемого метода.
Исключение методов
[ редактировать ]Если метод исключен из типажа, этот метод становится «обязательным» методом для этого типажа, поскольку его могут вызывать другие методы типажа.
Поддерживаемые языки
[ редактировать ]Черты родом из языка программирования Self. [5] и поддерживаются следующими языками программирования:
- AmbientTalk себе свойства свойств Self (множественное наследование на основе объектов) и свойств Smalltalk Squeak : сочетает в (требующих явного составления признаков программистом). Он основан на исследованиях свойств с сохранением состояния и замораживаемых свойств, чтобы обеспечить состояние внутри признаков, что не допускалось в первых определениях. [6]
- C# : Начиная с версии 8.0, C# поддерживает методы интерфейса по умолчанию . [7] которые обладают некоторыми свойствами признаков. [8]
- C++ : используется в стандартной библиотеке шаблонов и стандартной библиотеке C++ для поддержки универсальных классов контейнеров. [9] [10] и в библиотеке Boost TypeTraits. [11]
- Curl : Абстрактные классы как примеси допускают реализацию методов и, таким образом, представляют собой черты с другим именем. [ нужна ссылка ]
- Крепость [12]
- Groovy : начиная с версии 2.3. [13]
- Haskell : В Haskell трейты называются классами типов .
- Haxe : Начиная с версии 2.4.0. [14] Называется статическим расширением [15] в инструкции используется
using
ключевое слово - Java : Начиная с версии 8, Java поддерживает методы по умолчанию . [16] которые обладают некоторыми свойствами признаков. [17] [18] [19] [20]
- JavaScript : черты могут быть реализованы с помощью функций и делегирования. [21] или через библиотеки, предоставляющие черты. [22] [23] [24]
- Джулия : Некоторые пакеты реализуют особенности, например, [25]
- Котлин : трейты называются интерфейсами. [26] начиная с М12. [27]
- Лассо [28]
- Моджо : Начиная с версии 0.6.0. [29]
- OCaml : Трейты могут быть реализованы с использованием различных возможностей языка: включение модулей и типов модулей, функторы и типы функторов, наследование классов и типов классов и т. д.
- Perl : называются ролями , они реализованы в библиотеках Perl, таких как Moose , Role::Tiny и Role::Basic. Роли являются частью родственного языка Раку . [30] С принятием предложения Corinna OOP [31] Perl будет иметь собственные роли как часть современной ООП-системы.
- PHP : Начиная с версии 5.4, [32] [33] PHP позволяет пользователям указывать шаблоны, которые предоставляют возможность «наследовать» от более чем одного (признака) класса, как псевдомножественное наследование .
- Python : через стороннюю библиотеку, [34] [35] или через классы миксинов более высокого порядка [36]
- Racket : поддерживает черты в виде библиотеки и использует макросы, структуры и первоклассные классы для их реализации. [37]
- Ruby : миксины модулей можно использовать для реализации трейтов. [38]
- Ржавчина [39]
- Скала [40] [41] черта встроена и поддерживается ключевым словом
trait
. - Smalltalk : функции реализованы в двух диалектах Smalltalk, Squeak. [1] и Фаро . [42]
- Swift : Трейты могут быть реализованы с помощью расширений протокола . [43]
Примеры
[ редактировать ]С#
[ редактировать ]В C# 8.0 можно определить реализацию как член интерфейса.
using System;
namespace CSharp8NewFeatures;
interface ILogger
{
// Traditional interface methods
void Log(string message);
void LogError(Exception exception);
// Default interface method
void LogWarning(string message)
{
Console.WriteLine(message);
}
}
class Logger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
public void LogError(Exception exception)
{
Console.WriteLine(exception.ToString());
}
}
class Program
{
static void Main(string[] args)
{
ILogger logger = new Logger();
logger.LogWarning("Some warning message");
}
}
PHP
[ редактировать ]В этом примере используется черта для улучшения других классов:
// The template
trait TSingleton
{
private static $_instance = null;
private function __construct() {} // Must have private default constructor and be aware not to open it in the class
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
}
class FrontController
{
use TSingleton;
}
// Can also be used in already extended classes
class WebSite extends SomeClass
{
use TSingleton;
}
Это позволяет моделировать аспекты множественного наследования:
trait TBounding
{
public $x, $y, $width, $height;
}
trait TMoveable
{
public function moveTo($x, $y)
{
// …
}
}
trait TResizeable
{
public function resize($newWidth, $newHeight)
{
// …
}
}
class Rectangle
{
use TBounding, TMoveable, TResizeable;
public function fillColor($color)
{
// …
}
}
Ржавчина
[ редактировать ]Трейт в Rust объявляет набор методов, которые должен реализовать тип. [44] Компиляторы Rust требуют эксплицирования трейтов, что обеспечивает безопасность дженериков в Rust.
// type T must have the "Ord" trait
// so that ">" and "<" operations can be done
fn max<T: Ord>(a: &[T]) -> Option<&T> {
let mut result = a.first()?;
for n in a {
if *n > *result {
result = &n;
}
}
Some(result)
}
Чтобы упростить утомительную и повторяющуюся реализацию таких черт, как Debug
и Ord
, derive
Макрос можно использовать для запроса компиляторов автоматически генерировать определенные реализации. [45] К производным признакам относятся: Clone
, Copy
, Debug
, Default
, PartialEq
, Eq
, PartialOrd
, Ord
и Hash
.
См. также
[ редактировать ]- Метод расширения
- Интерфейс (объектно-ориентированное программирование)
- Параметрический полиморфизм
- УФКС
Ссылки
[ редактировать ]- ^ Jump up to: а б с Шерли, Натанаэль; Дюкасс, Стефан; Ньерстраз, Оскар ; Блэк, Эндрю П. (2003). «Черты характера: составные единицы поведения» (PDF) . Материалы Европейской конференции по объектно-ориентированному программированию (ECOOP) . Конспекты лекций по информатике. 2743 . Спрингер: 248–274. CiteSeerX 10.1.1.1011.8 . дои : 10.1007/978-3-540-45070-2_12 . ISBN 978-3-540-45070-2 .
- ^ Дюкасс, Стефан; Ньерстраз, Оскар; Шерли, Натанаэль; Вуйтс, Роэл; Блэк, Эндрю П. (март 2006 г.). «Черты: механизм мелкозернистого повторного использования». Транзакции ACM в языках и системах программирования . 28 (2): 331–388. CiteSeerX 10.1.1.64.2480 . дои : 10.1145/1119479.1119483 . S2CID 16434119 .
- ^ Фишер, Кэтлин ; Реппи, Джон (2003). «Статически типизированные черты» (PDF) . Чикагский университет . Архивировано (PDF) из оригинала 17 мая 2004 г.
{{cite journal}}
: Для цитирования журнала требуется|journal=
( помощь ) - ^ Фишер, Кэтлин; Реппи, Джон (2004). Типизированное исчисление признаков (PDF) . 11-й семинар по основам объектно-ориентированного программирования . Чикагский университет .
- ^ Карри, Гаэль; Баер, Ларри; Липки, Дэниел; Ли, Брюс (1982). Черты: подход к созданию подклассов с множественным наследованием . Конференция SIGOA по офисным информационным системам. Филадельфия, Пенсильвания, США: ACM Press. стр. 1–9. дои : 10.1145/966873.806468 .
- ^ Ван Катсем, Том; Бергель, Александр; Дюкасс, Стефан; Де Мойтер, Вольфганг (2009). Добавление контроля состояния и видимости к признакам с использованием лексической вложенности (PDF) . Европейская конференция по объектно-ориентированному программированию (ECOOP 2009). Конспекты лекций по информатике. Том. 5653. Шпрингер-Верлаг. стр. 220–243. CiteSeerX 10.1.1.372.1265 . дои : 10.1007/978-3-642-03013-0_11 . ISBN 978-3-642-03012-3 .
- ^ «Методы интерфейса по умолчанию» . Что нового в C# 8.0 . Майкрософт . Проверено 29 ноября 2019 г.
- ^ «Интерфейсы в C# 8.0 претерпевают изменения» . Реализация по умолчанию в интерфейсах C# 8.0 . Говоря о Дотнете. 9 сентября 2019 года . Проверено 29 ноября 2019 г.
- ^ "iterator_traits<Итератор>" . Стандартная библиотека шаблонов . СГИ.
- ^ Майерс, Натан К. (июнь 1995 г.). «Черты: новая и полезная техника шаблонов» . Отчет С++ . Проверено 23 января 2016 г.
- ^ Абрахамс, Дэвид. «Общие методы программирования: особенности» . Библиотеки Boost C++ . Проверено 23 января 2016 г.
- ^ Стил, Гай; Мессен, Ян-Виллем (11 июня 2006 г.). «Учебник по языку программирования Fortress» (PDF) . Сан Микросистемс . Проверено 23 января 2016 г.
- ^ «Объектное ориентирование: особенности» . Язык программирования Groovy . Проверено 23 января 2016 г.
- ^ «Haxe 2.4.0 — Haxe — Кроссплатформенный набор инструментов» . Haxe — Кроссплатформенный набор инструментов . Проверено 12 сентября 2017 г.
- ^ «Руководство — Haxe — Кроссплатформенный набор инструментов» . Haxe — Кроссплатформенный набор инструментов . Проверено 12 сентября 2017 г.
- ^ «Методы по умолчанию» . Учебники по Java . Оракул . Проверено 23 января 2016 г.
- ^ Ликори, Луиджи; Спивак, Арно (2008). «FeatherTrait: скромное расширение полулегкой Java» . Транзакции ACM в языках и системах программирования . 30 (2): 11:1. дои : 10.1145/1330017.1330022 . S2CID 17231803 .
- ^ Ликори, Луиджи; Спивак, Арно (2008). «Расширение FeatherTrait Java с помощью интерфейсов» . Теоретическая информатика . 398 (1–3): 243–260. дои : 10.1016/j.tcs.2008.01.051 . S2CID 12923128 .
- ^ Боно, Вивиана; Менса, Энрико; Наддео, Марко (сентябрь 2014 г.). Специализированное программирование на Java 8 . Международная конференция по принципам и практикам программирования на платформе Java: виртуальные машины, языки и инструменты (PPPJ '14) . стр. 181–6. CiteSeerX 10.1.1.902.161 . дои : 10.1145/2647508.2647520 .
- ^ Форслунд, Эмиль (3 февраля 2016 г.). «Определение шаблона свойств в Java» . Эпоха Явы . Архивировано из оригинала 4 августа 2016 года . Проверено 3 февраля 2016 г.
- ^ Селигер, Петр (11 апреля 2014 г.). «Множество талантов JavaScript» . Проверено 23 января 2015 г.
- ^ «Traits.js: особенности для JavaScript» . Проверено 23 января 2016 г.
- ^ Ван Катсем, Том; Миллер, Марк С. (2012). «Надежная композиция признаков для Javascript» (PDF) . Наука компьютерного программирования . Проверено 23 января 2016 г.
- ^ «КоктейльJS» . Проверено 23 января 2016 г.
- ^ мауро3. "SimpleTraits.jl" . Гитхаб . Проверено 23 марта 2017 г.
{{cite web}}
: CS1 maint: числовые имена: список авторов ( ссылка ) - ^ «Интерфейсы» . Справочник по Котлину . ДжетБрэйнс . Проверено 23 января 2016 г.
- ^ Бреслав, Андрей (29 мая 2015 г.). «Котлин M12 вышел!» . Котлин-блог . ДжетБрэйнс . Проверено 23 января 2016 г.
- ^ "Черты" . Руководство по языку Лассо . ЛассоСофт. 6 января 2014 года . Проверено 23 января 2016 г.
- ^ «Модульная документация — журнал изменений Mojo🔥» . docs.modular.com . Проверено 13 декабря 2023 г.
- ^ хроматический (30 апреля 2009 г.). «Почему роли Perl» . Проверено 23 января 2016 г.
- ^ Кертис «Овидий» По. «Предложение Коринны ООП» . Коринна RFC . Проверено 30 сентября 2022 г.
- ^ "Черты" . PHP-документация . Группа PHP . Проверено 23 января 2016 г.
- ^ Марр, Стефан (9 января 2011 г.). «Запрос комментариев: горизонтальное повторное использование PHP» . PHP.net вики . Группа PHP . Проверено 31 января 2011 г.
- ^ Давай, Теппо. «Документация py3traits» . Проверено 23 января 2016 г.
- ^ Перя, Теппо (25 марта 2015 г.). "py2traits" . Гитхаб . Проверено 23 января 2016 г.
- ^ «Классы миксинов высшего порядка» . Архивировано из оригинала 9 октября 2016 г.
- ^ "Черты" . Справочник по рэкету . Проверено 23 января 2016 г.
- ^ Дэвид Нэсби (14 февраля 2004 г.). «Черты Рубина» . Руби Нэсби . Проверено 23 января 2016 г.
- ^ "Черты" . Язык программирования Rust . Проверено 30 сентября 2019 г.
- ^ "Черты" . Экскурсия по Скале . Федеральная политехническая школа Лозанны . Проверено 23 января 2016 г.
- ^ Ньюард, Тед (29 апреля 2008 г.). «Руководство для занятого Java-разработчика по Scala: особенности и поведение» . IBM DeveloperWorks . ИБМ . Проверено 23 января 2016 г.
- ^ «Черты характера за 10 минут» . Фаро: Книга CollaborActive . Проверено 23 января 2016 г.
- ^ Холлеманс, Маттейс (22 июля 2015 г.). «Миксины и трейты в Swift 2.0» . Проверено 23 января 2016 г.
- ^ «Трейты — Введение в программирование с использованием Rust» .
- ^ «Трейты — язык программирования Rust» .
Внешние ссылки
[ редактировать ]- «Черты: составные единицы поведения» . Группа создания программного обеспечения . Университет Берна.