オブジェクト指向プログラミングの6.4。Scalaのトレイト
インターフェイスとして形質6.4.1
- 特別なコンセプトでScalaのトレイト。
- まず、第1インタフェース形質として、Javaインタフェース(インタフェース)で形質で、この場合に非常に類似しています。
- 抽象メソッドは限り方法は身体への道を与えないよう、抽象クラスの抽象メソッドとして、特性に定義されていることができます。
- クラスは使用することができ、これが実装されていないことに注意して、キーワード継承された形質を拡張しますが、拡張し、Scalaでは概念を実装していないにかかわらず、クラスや継承された形質の、統一されている拡張。
- クラス継承した後、我々は実装されている場合は、overrideキーワードを使用する必要はありません、ここで抽象メソッドを実装する必要があります。
- Scalaはクラスのために多重継承をサポートしていますが、キーワードを使用して、多重継承の形質をサポートしていません。
- クラスAは、クラスBを拡張します
- クラスAは、クラスCを拡張します
- 例えば:
パッケージ cn.itcast.triat 形質 HelloTrait { DEF:ユニットのsayHello() } 形質 MakeFriendsTrait { DEF makeFriends(C:子供):単位は } //多重继承形質クラスの子供(ヴァル名:文字列)が延び HelloTraitを有する MakeFriendsTrait と Cloneableを有するシリアライズ{ デフのsayHello()= のprintln( "こんにちは、" + この .nameの)デフ makeFriends(C:子供)= のprintln(+ "こんにちは、私の名前は" この
.nameの+ + c.name) "あなたの名前は"
}
オブジェクト子供{
DEF配列[文字列]){:メイン(引数
ヴァル C1 = 新しい子供("トム")
ヴァル C2 = 新しい子供("ジム")
C1 .sayHello()//こんにちは、トム
c1.makeFriends(C2)//こんにちは、私の名前はトムです、あなたの名前はジムです
}
}
6.4.2。形質に定義された具体的な方法
- 唯一の抽象メソッドを定義することができScalaの形質において、方法は、一般的な方法を含むツールのようなこの時間形質において、その形質はまた、機能のクラスを含むことができ、具体的に定義することができます。
- 例えば:
- Scalaの形質を受け継い形質サブクラスフィールド形質が自動的に定義得られ、この時点で、特定のフィールドに定義することができます。
- しかし、このフィールドを得るための方法と継承クラスが異なっています。取得は、フィールドクラスを継承している場合、実際には、それは、親クラスで定義された、サブクラスに追加することが直接取得し、フィールドの特性を継承します。
- 例えば:
パッケージ cn.itcast.triatは
/ **
* このような形質は、多くのサブクラスは、一般的な方法、例えば、印刷法などのログや他のツールです含まれていてもよいです。
*スパーク使用上の特徴は、共通のログ記録方式を定義する。
* /
形質ロガー{
DEF(メッセージ:文字列):ログ単位= のprintln(メッセージ)
}
クラス PersonForLog(ヴァルの名:文字列)に延びロガー{
DEF makeFriends(OTHER:PersonForLog )= {
printlnの( "こんにちは、" + other.name + + "!私の名前は" この .nameの+ "Iミスあなた!!")
、この.logの( "[+ other.name + makeFriends方法がパラメータPersonForLog名= "]"で呼び出される")
}
}
オブジェクト PersonForLog {
DEFメイン(引数:配列[文字列]){
ヴァル P1 = 新しい PersonForLog( "ジャック")
ヴァル P2 = 新 PersonForLog( "バラ")
p1.makeFriends(P2)
//こんにちは、バラ!私の名前は、私はあなたを欠場、ジャックです!
// makeFriensメソッドは、パラメータPersonForLogで呼び出された[名前=ローズ]
}
}
6.4.3。特定のフィールドが特色で定義されています
パッケージ cn.itcast.triat
形質 PersonForField {
ヴァルの 年齢:のInt = 50
}
直接サブクラスに追加取得//継承されたフィールドトレイト
クラス StudentForField(ヴァルの名:文字列)拡張 PersonForFieldは{
DEFのsayHelloは= のprintln(「こんにちは、私は」+ この .nameの+「を、私の時代です」+ 年齢)
}
オブジェクト StudentForField {
DEFメイン(引数:配列[文字列]){
ヴァル S = 新しい StudentForField( "トム")
s.sayHello
}
}
6.4.4。トレイトで抽象的なフィールドに定義され
- Scalaの形質は、抽象フィールドで定義することができ、具体的な方法はまた、抽象フィールドに基づいて形質で調製することができます。
- クラスは、抽象フィールドが特定の値を提供し、カバーしなければならない形質を継承しました。
- 例えば:
パッケージ cn.itcast.triat 形質 SayHelloTrait { ヴァルの MSG:文字列DEFのsayHello(名:文字列)= のprintln(MSG + "" +名) } クラス PersonForAbstractField(ヴァル名:文字列)が延び SayHelloTrait { //必须覆盖抽象フィールドヴァルをMSG = "こんにちは" DEF makeFriends(その他:PersonForAbstractField)= { この .sayHello(other.name)のprintln(+ "私は" この .nameの+ "私はあなたと友達になりたい!!") } } オブジェクト PersonForAbstractField { DEF
メイン(引数:配列[文字列]){
ヴァル P1 = 新しい PersonForAbstractField( "トム")
ヴァル P2 = 新しい PersonForAbstractField( "ローズ")
p1.makeFriends(P2)
}
}
混合形質を指定されたオブジェクトのインスタンスにおいて6.4.5
- オブジェクトのオブジェクト・クラスを作成することができるとき形質を混合指定、及び形質を有する方法、および他のそのようなオブジェクトの唯一の混合ターゲット形質ではありません。
- あなたがオブジェクトを作成すると、使用キーワードは形質と混合指定します。
- 例えば:
- Scalaのサポートは、複数のクラスの継承形質を可能にした後、今度はついにsuperキーワードを実行するために、限り、複数の形質のと同じ方法として、複数の特性に同じメソッドを呼び出すことができます。
- 複数の形質コールクラスの両方で、この方法は、それが最初の右端の実行方法の形質を開始すると、その後、呼び出しチェーンを形成するために、実行するために左折。
- この機能は、実際には、実現のChain of Responsibilityパターンのデザインパターンで、非常に強力です。
- ケース説明:
パッケージ cn.itcast.triat 形質 {LoggedTrait //これは、特定の方法で実行される方法のあるDEFの:= {}ログ(文字列MSG) } 形質 MyLogger 延び LoggedTrait { //覆うログを()のメソッドオーバーライドDEFのログ(MSG:文字列)= printlnは( "ログ:" + MSG) } クラス PersonForMixTraitMethod(ヴァルの名:文字列)拡張 LoggedTrait { DEFのsayHello = { printlnの( "こんにちは、私よ" + この .nameの) ログ( "のsayHelloメソッドを呼び出されました!") } } オブジェクト {PersonForMixTraitMethodをDEF
メイン(引数:配列[文字列]){
ヴァルトム= 新新 PersonForMixTraitMethod(「トム」)//のsayHello結果:.こんにちは、私だトムは
// MyLogger混合キーワード指定された形質に使用
ヴァルローズ= 新新(PersonForMixTraitMethod 「ローズ」)と MyLogger
rose.sayHello
//結果は:こんにちは、私はローズだ
ログ:!のsayHelloメソッドは、呼び出される://結果は
}
}
6.4.6。形質コールチェーン
パッケージ cn.itcast.triat 形質 HandlerTraitは{ DEFハンドル(データ:文字列)= { のprintln( "最後")} } 形質 DataValidHandlerTraitが延び HandlerTrait { DEF上書き処理(データ:文字列)= { のprintln( "データを確認してください。" +データ)スーパー .handle(データ) } } 形質 SignatureValidHandlerTraitは延び HandlerTrait { DEFオーバーライド文字列)= {ハンドル(データのprintln( "署名を確認してください。" +データ)スーパー .handle(データ) } } クラスを
PersonForRespLine(ヴァルの名:文字列)が延び SignatureValidHandlerTraitを有する DataValidHandlerTrait {
DEFのsayHello = {
のprintln( "こんにちは、" + この .nameの)
この .handle(この .nameの)
}
}
オブジェクト PersonForRespLine {
DEFメイン(引数:配列[文字列]) {
ヴァル P = 新しい PersonForRespLine( "トム")
p.sayHello
//执行结果:
//こんにちは、トム
//チェックデータ:トム
//署名をチェック:トム
//最後
}
}
6.4.7。の構築機構トレイト
- また、構成コード形質スカラにおいて、形質、すなわち、コードの方法のいずれかを含んでいません。
- サブクラスは、形質を継承し、次のように、構築メカニズムは次のとおりです。
- 複数の形質を実行するために、左から右へ;親クラスの最初の実装のコンストラクタ、クラスタイプが左端に配置しなければならない形質を構築し、複数の形質が同じ親の形質を継承した場合、最初に親形質を構築し、形質は、親ます構造;すべての設定が完了した後、形質、最後に実行されたサブクラスのコンストラクタ。
- 例えば:
パッケージ cn.itcast.triat クラス Person_One { printlnの( "人物のコンストラクタ!") } トレイト Logger_One { printlnの( "ロガーのコンストラクタ!") } トレイト MyLogger_Oneが拡張 Logger_One { printlnの( "MyLoggerのコンストラクタを!") } トレイト TimeLogger_Oneが拡張 Logger_Oneを{ printlnの( "TimeLoggerのコンストラクタ!") } クラス Student_Oneは拡張 Person_Oneをして MyLogger_One で TimeLogger_One { printlnの( "学生」コンストラクタ!」)
}
オブジェクト exe_one {
defのメイン(引数:配列[文字列]):単位= {
valの学生= 新 Student_One
//执行结果为:
//人のコンストラクタ!
//ロガーのコンストラクター!
// MyLoggerのコンストラクター!
// TimeLoggerのコンストラクタ!
//学生のコンストラクター!
}
}
6.4.8。形質継承されたクラス
- Scalaのトレイトでクラスを継承することができ、クラスはすべてのスーパーの親となり、この時間は、サブクラスの形質を継承しました。
- クラスA
- 形質BはAに延び
- クラスCはBを拡張します
- 形質DがBを拡張
- 例えば:
パッケージ cn.itcast.triat クラス MyUtil { DEF:= printMsg(文字列MSG)のprintln(MSG) } 形質 Logger_Twoが延び MyUtilを{ DEFログ(MSG:文字列)= この .printMsg( "ログ:" + MSG) } クラス Person_Three(ヴァル・名:文字列)拡張 Logger_Two { デフのsayHello { この .logの(+ "こんにちは、私は" この .nameの)この .printMsg(+ "こんにちは、私は" この .nameの) } } オブジェクト Person_Three { デフを
メイン(引数:配列[文字列]){
valを P = 新 Person_Three( "トム")
p.sayHello
//执行结果:
//ログイン:こんにちは、私だトム
//こんにちは、私はトム
}
}