Set of methods that extend the functionality of a class
コンピュータプログラミング において 、 特性とは クラス の機能を拡張するために使用できる 一連の メソッドを表す 言語 概念である 。 [1] [2]
根拠
オブジェクト指向プログラミングでは、互いに関連のないクラス間で動作が共有されることがあります。例えば、関連のない多くのクラスが、オブジェクトを JSON に シリアル化する メソッドを持つ場合があります。これまで、動作を必要とするすべてのクラスでコードを重複させることなく、この問題を解決するためのアプローチがいくつかありました。他のアプローチとしては 多重継承 や ミックスインなど がありますが、これらには欠点があります。ミックスインの適用順序が変更されたり、親クラスやミックスインに新しいメソッドが追加されたりすると、コードの動作が予期せず変更される可能性があります。
トレイトは、クラスがトレイトを使用して目的の動作を実現できるようにすることで、これらの問題を解決します。クラスが複数のトレイトを使用する場合、トレイトの使用順序は関係ありません。トレイトによって提供されるメソッドは、クラスのデータに直接アクセスできます。
特徴
トレイトは、プロトコル(インターフェース) と ミックスイン の側面を組み合わせたものです 。インターフェースと同様に、トレイトは1つ以上の メソッドシグネチャ を定義し、実装クラスはそれらのメソッドシグネチャを実装する必要があります。ミックスインと同様に、トレイトは実装クラスに追加の動作を提供します。
異なる特性によって提供されるメソッド間で名前の衝突 が発生した場合 、プログラマーはクラス内でどのメソッドを使用するかを明示的に明確にする必要があります。つまり、 多重継承 の ダイヤモンド問題 を手動で解決することになります。これは、名前の衝突がスコープ規則 によって自動的に解決されるオブジェクト指向プログラミングの他の合成方法とは異なります 。
特性を使って実行できる操作には以下のものがある: [3] [4]
対称和 :2つの互いに素な特性を結合して新しい特性を作成する演算
オーバーライド (または 非対称和 ):既存の特性にメソッドを追加して新しい特性を形成する操作。場合によっては、 そのメソッドの一部を オーバーライドする。
エイリアス : 既存のメソッドに新しい名前を追加して新しい特性を作成する操作
除外 : 既存のトレイトからメソッドを削除して新しいトレイトを作成する操作。(これをエイリアス操作と組み合わせると、 浅い名前変更 操作になります)。
メソッドがトレイトから除外されている場合、そのメソッドはトレイトを利用するクラス、またはそのクラスの親クラスによって提供されなければなりません。これは、トレイトによって提供されるメソッドが除外されたメソッドを呼び出す可能性があるためです。
特性合成は 可換性 (特性 A と特性 B が与えられたとき、 A + Bは B + A と等しい )かつ 結合性 (特性 A 、 B 、 C が与えられたとき、( A + B )+ Cは A +( B + C ) と等しい)である。 [1]
制限事項
特性は多くの選択肢に比べて大きな利点を提供しますが、特性自体にも制限があります。
必要なメソッド
トレイトが利用クラスに特定のメソッドの提供を要求する場合、トレイトはそれらのメソッドが トレイトのニーズと 意味的に同等かどうかを判断できません。Perlなどの一部の動的言語では、要求されるメソッドはメソッド名でしか識別できず、完全な メソッドシグネチャで は識別できないため、要求されるメソッドが適切であることを保証することが難しくなります。
除外方法
メソッドがトレイトから除外されている場合、そのメソッドはトレイトのその他のメソッドによって呼び出される可能性があるため、トレイトの「必須」メソッドになります。
サポートされている言語
特性は元々プログラミング言語 Self [5] に由来し、以下のプログラミング言語でサポートされています。
例
C#
C# 8.0 では、実装をインターフェースのメンバーとして定義できます。
システム を使用します 。
名前空間 CSharp8NewFeatures ;
interface ILogger { // 従来のインターフェイス メソッド void Log ( string message ); void LogError ( Exception exception );
// デフォルトのインターフェースメソッド void LogWarning ( string message ) { Console.WriteLine ( message ) ; } }
クラス Logger : ILogger { public void Log ( 文字 列 message ) { Console.WriteLine ( メッセージ ) ; }
public void LogError ( 例外 exception ) { Console.WriteLine ( 例外 .ToString ( ) ) ; } }
パブリック クラス Program { static void Main ( string [] args ) { ILogger logger = new Logger ();
logger . LogWarning ( "何らかの警告メッセージ" );
} }
PHP
この例では、特性を使用して他のクラスを強化します。
// テンプレート
特性 TSingleton
{
private static $_instance = null ;
private function __construct () {} // プライベートなデフォルトコンストラクタが必要であり、クラス内で開かないように注意する必要がある
パブリック 静的 関数 getInstance ()
{
if ( null === self :: $_instance ) {
self :: $_instance = new self ();
}
self :: $_instance を 返し ます 。
クラス FrontController
{
TSingleton を使用します ; }
// すでに拡張されたクラスでも使用できます
class WebSite extends SomeClass
{
use TSingleton ;
}
これにより、多重継承の側面をシミュレートできます。
特性 TBounding
{
public $x 、 $y 、 $width 、 $height ;
}
TMoveable
特性 {
パブリック 関数 moveTo ( $x , $y )
{
// …
}
}
特性 TResizeable
{
パブリック 関数 resize ( $newWidth , $newHeight )
{
// …
}
}
クラス Rectangle
{
TBounding 、 TMoveable 、 TResizeable を 使用します 。
パブリック 関数 fillColor ( $color )
{
// …
}
}
さび
Rustのトレイトは型が実装しなければならないメソッドのセットを宣言します。 [44] Rustコンパイラはトレイトを明示的に指定する必要があり、これによりRustの ジェネリック の安全性が保証されます 。
// 型 T は "Ord" 特性を持たなければなりません
// そのため ">" と "<" 演算が行えます
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、、、、、、、、、 および など があります 。
CopyDebugDefaultPartialEqEqPartialOrdOrdHash
参照
参考文献
^ abc Schärli, Nathanael; Ducasse, Stéphane; Nierstrasz, Oscar ; Black, Andrew P. (2003). 「特性:動作の構成単位」 (PDF) . ヨーロッパオブジェクト指向プログラミング会議(ECOOP)議事録 . コンピュータサイエンス講義ノート. 第2743巻. Springer. pp. 248– 274. CiteSeerX 10.1.1.1011.8 . doi :10.1007/978-3-540-45070-2_12. ISBN 978-3-540-45070-2 。
^ Ducasse, Stéphane; Nierstrasz, Oscar; Schärli, Nathanael; Wuyts, Roel; Black, Andrew P. (2006年3月). 「Traits: 細粒度再利用のためのメカニズム」. ACM Transactions on Programming Languages and Systems . 28 (2): 331– 388. CiteSeerX 10.1.1.64.2480 . doi :10.1145/1119479.1119483. S2CID 16434119.
^ Fisher, Kathleen ; Reppy, John (2003). Statically typed traits (PDF) (レポート). シカゴ大学 . 2004年5月17日時点のオリジナルより アーカイブ (PDF) 。
^ フィッシャー、キャスリーン、レピー、ジョン (2004). 特性の型付き計算 (PDF) . 第11回オブジェクト指向プログラミングの基礎に関するワークショップ. シカゴ大学 .
^ Curry, Gael; Baer, Larry; Lipkie, Daniel; Lee, Bruce (1982). Traits: 多重継承サブクラス化へのアプローチ . SIGOA Conference on Office Information Systems. フィラデルフィア、ペンシルベニア州、米国: ACM Press. pp. 1– 9. doi :10.1145/966873.806468.
^ Van Cutsem, Tom; Bergel, Alexandre; Ducasse, Stéphane; De Meuter, Wolfgang (2009). 語彙ネストを用いた特性への状態および可視性制御の追加 (PDF) . ヨーロッパオブジェクト指向プログラミング会議 (ECOOP 2009). コンピュータサイエンス講義ノート. 第5653巻. Springer-Verlag. pp. 220– 243. CiteSeerX 10.1.1.372.1265 . doi :10.1007/978-3-642-03013-0_11. ISBN 978-3-642-03012-3 。
^ 「既定のインターフェイスメソッド」。C # 8.0 の新機能 。Microsoft 。 2019年 11月29日 閲覧 。
^ 「C# 8.0 のインターフェースが刷新されました」。C # 8.0 のインターフェースにおけるデフォルトの実装 。Talking Dotnet。2019年9月9日。 2019年 11月29日 閲覧 。
^ "iterator_traits<Iterator>". 標準テンプレートライブラリ . SGI.
^ Myers, Nathan C. (1995年6月). 「Traits: 新しく有用なテンプレートテクニック」. C++ Report . 2016年 1月23日 閲覧 。
^ Abrahams, David. 「ジェネリックプログラミングテクニック:特性」. Boost C++ ライブラリ . 2016年 1月23日 閲覧。
^ Steele, Guy; Maessen, Jan-Willem (2006年6月11日). 「Fortressプログラミング言語チュートリアル」 (PDF) . Sun Microsystems . 2016年 1月23日 閲覧 。
^ 「オブジェクト指向:特性」。Groovy プログラミング言語。 2016年 1月23日 閲覧 。
^ 「Haxe 2.4.0 - Haxe - クロスプラットフォーム・ツールキット」。Haxe - クロスプラットフォーム・ツールキット 。 2017年9月12日 閲覧。
^ 「マニュアル - Haxe - クロスプラットフォームツールキット」。Haxe - クロスプラットフォームツールキット 。 2017年9月12日 閲覧。
^ 「デフォルトメソッド」。Java チュートリアル 。Oracle 。 2016年 1月23日 閲覧 。
^ Liquori, Luigi; Spiwack, Arnaud (2008). 「FeatherTrait: Featherweight Javaの控えめな拡張」. ACM Transactions on Programming Languages and Systems . 30 (2): 11:1. doi : 10.1145/1330017.1330022 . S2CID 17231803.
^ Liquori, Luigi; Spiwack, Arnaud (2008). 「インターフェースによるFeatherTrait Javaの拡張」. 理論計算機科学 . 398 ( 1–3 ): 243– 260. doi : 10.1016/j.tcs.2008.01.051 . S2CID 12923128.
^ Bono, Viviana; Mensa, Enrico; Naddeo, Marco (2014年9月). Java 8における特性指向プログラミング. Javaプラットフォームにおけるプログラミングの原則と実践に関する国際会議:仮想マシン、言語、ツール (PPPJ '14). pp. 181–6 . CiteSeerX 10.1.1.902.161 . doi :10.1145/2647508.2647520.
^ Forslund, Emil (2016年2月3日). 「Javaにおける特性パターンの定義」. Age of Java . 2016年8月4日時点のオリジナルよりアーカイブ。 2016年 2月3日 閲覧 。
^ Seliger, Peter (2014年4月11日). 「JavaScriptの多彩な才能」 . 2015年 1月23日 閲覧 。
^ 「Traits.js: JavaScript 用 Traits」 . 2016年 1月23日 閲覧 。
^ Van Cutsem, Tom; Miller, Mark S. (2012). 「Javascript のための堅牢な特性合成」 (PDF) . Science of Computer Programming . 2016年 1月23日 閲覧 。
^ "CocktailJS" . 2016年 1月23日 閲覧 。
^ Mauro Werder. 「SimpleTraits.jl」. GitHub . 2017年 3月23日 閲覧 。
^ 「インターフェース」. Kotlinリファレンス . JetBrains . 2016年 1月23日 閲覧 。
^ Breslav, Andrey (2015年5月29日). 「Kotlin M12がリリースされました!」 Kotlinブログ . JetBrains . 2016年 1月23日 閲覧 。
^ 「特性」。 なげなわ言語ガイド 。ラッソソフト。 2014 年 1 月 6 日 。 2016 年 1 月 23 日 に取得 。
^ 「Modular Docs - Mojo🔥の変更ログ」. docs.modular.com . 2023年12月13日 閲覧。
^ chromatic (2009年4月30日). 「Perlのロールの理由」 . 2016年 1月23日 閲覧 。
^ Curtis "Ovid" Poe. 「Corinna OOP 提案」. Corinna RFC . 2022年 9月30日 閲覧 。
^ 「特性」。PHP ドキュメント 。PHPグループ。 2016年 1月23日 閲覧 。
^ Marr, Stefan (2011年1月9日). 「Request for Comments: Horizontal Reuse for PHP」. PHP.net wiki . PHPグループ. 2011年 1月31日 閲覧 。
^ ペラ、テッポウ。 「py3traits ドキュメント」 。 2016 年 1 月 23 日 に取得 。
^ ペラ、鉄砲 (2015-03-25)。 「py2traits」。 GitHub 。 2016 年 1 月 23 日 に取得 。
^ 「Higher Order Mixin Classes」。2016年10月9日時点のオリジナルよりアーカイブ。
^ 「特性」. The Racket Reference . 2016年 1月23日 閲覧 。
^ David Naseby (2004年2月14日). 「Rubyにおける特性」. Ruby Naseby . 2016年 1月23日 閲覧 。
^ “Traits”. Rustプログラミング言語 . 2019年 9月30日 閲覧。
^ 「特性」。 スカラ座のツアー 。 ローザンヌ連邦工科大学 。 2016 年 1 月 23 日 に取得 。
^ Neward, Ted (2008年4月29日). 「多忙なJava開発者のためのScalaガイド:特性と動作について」. IBM developerWorks . IBM . 2016年 1月23日 閲覧 。
^ 「10分でわかる特性」 Pharo: The CollaborActive Book . 2016年 1月23日 閲覧 。
^ ホレマンズ、マタイス (2015 年 7 月 22 日)。 「Swift 2.0 のミックスインとトレイト」 。 2016 年 1 月 23 日 に取得 。
^ 「Traits - Rustを使ったプログラミング入門」。2023年5月29日時点のオリジナルよりアーカイブ。
^ 「Traits - Rust プログラミング言語」。
外部リンク
「特性:構成可能な動作単位」 ソフトウェア構成グループ 、ベルン大学。