Java7インターフェース:フィールドと抽象メソッドのみを定義できます
Java8インターフェース:フィールドと抽象メソッドを定義し、デフォルトのメソッドを実装できます
その場合、Scalaの特性はJava8のインターフェースに似ています
それは、抽象メソッドと通常のメソッド(実装されたメソッド)の定義を実行することです。
Java 8のインターフェースは、盗用されたScalaの特性です。
しかし、トレイトには他にも多くの機能があります
Java8のインターフェース-★
Java 8のインターフェースは、JavaによってコピーされたScalaの特性です。
package cn. hanjiaxiaozhi. traitdemo;
public class InterfaceDemo {
public static void main( String [ ] args) {
IPhone iPhone = new IPhone( ) ;
XiaoMi xiaoMi = new XiaoMi( ) ;
iPhone. call( ) ;
iPhone. video( ) ;
xiaoMi. call( ) ;
xiaoMi. video( ) ;
}
}
interface Phone {
void call( ) ;
default void video( ) {
System. out. println( "Phone video" ) ;
}
}
class IPhone implements Phone {
@Override
public void call( ) {
System. out. println( "IPhone call" ) ;
}
}
class XiaoMi implements Phone {
@Override
public void call( ) {
System. out. println( "XiaoMi call" ) ;
}
}
インターフェースとして使用される特性-マスター-★★★
インターフェースとしての特性
Scalaのトレイトは特別な概念であり、Javaのインターフェースと非常によく似ています。
(Java8のインターフェースの新機能:デフォルトのメソッドと静的メソッドはScalaからコピーされます!)
注意:
クラスはextendsキーワードを使用して特性を継承できます
実装されていないが拡張されていることに注意してください。Scalaには実装の概念はありません。継承や特性に関係なく、均一性は拡張されます。
Scalaは、Javaと同様に、多重継承クラスをサポートしていませんが、多重継承特性をサポートしています。withキーワードを使用するだけです。
トレイトで抽象メソッドを定義する
抽象メソッドはトレイトで定義できます。クラスの継承後、抽象メソッドを実装する必要があります。overrideキーワードは必須ではありません。追加することをお勧めします。
トレイトで抽象フィールドを定義する
トレイトは、トレイト内の抽象フィールドを定義することもできます。トレイトを継承するクラスの場合、トレイトは抽象フィールドをカバーし、特定の値を提供する必要があります。
トレイトで特定のメソッドを定義する
特性で抽象的なメソッドを定義できるだけでなく、具体的なメソッドも定義できます
特性に特定のフィールドを定義する
トレイトで特定のフィールドを定義できます。この時点で、トレイトを継承するサブクラスは、トレイトで定義されたフィールドを自動的に取得します。
ただし、このフィールドの取得方法は、クラスの継承とは異なります。
クラスを継承して取得したフィールドが実際に親クラスで定義されている場合
特性を継承して取得したフィールドの場合は、サブクラスに直接追加されます
package cn. hanjiaxiaozhi. traitdemo
trait HelloTrait {
def sayHello( ) : Unit
def log( message: String ) : Unit = {
println( message)
}
val id: Long
val age: Int = 18
}
trait MakeFriendsTrait {
def makeFriends( c: Children) : Unit
}
class Children( val name: String ) extends HelloTrait with MakeFriendsTrait with Cloneable with Serializable {
override def sayHello( ) : Unit = {
println( "hello " + name)
}
override val id: Long = 1
override def makeFriends( c: Children) : Unit = {
println( "hello my name is " + name + " my age is " + age + " your name is " + c. name)
}
}
object TestTrait{
def main( args: Array[ String ] ) : Unit = {
val jack = new Children( "jack" )
val tom = new Children( "tom" )
jack. sayHello
jack. makeFriends( tom)
}
}
特性はクラスを継承できます-理解-★
トレイトはクラスを継承することもでき、クラスのすべてのメンバーを継承します
package cn. hanjiaxiaozhi. traitdemo
class MyUtil {
def printMsg( msg: String ) = {
println( msg)
}
}
trait LogUtil extends MyUtil{
def log( msg: String ) = {
this . printMsg( msg)
}
}
class Person( val name: String ) extends LogUtil{
def sayHello( ) = {
this . log( "hello " + name)
}
}
object TestTrait2{
def main( args: Array[ String ] ) : Unit = {
new Person( "jack" ) . sayHello( )
}
}
特性に混合されたオブジェクト-理解-★
オブジェクトをインスタンス化するときに、withキーワードを使用して特性を組み合わせることができるため、オブジェクトに機能を動的に追加できます。
val / varオブジェクト名=特性を持つ新しいクラス
オブジェクトを作成するときにトレイトを混在させることができ、オブジェクトはトレイトにメソッドを持ちます
これはTraitの高度な機能です。理解してください。自分で開発するときに使用することはめったにありません。
package cn. hanjiaxiaozhi. traitdemo
class UserService{
}
trait Printer{
def myPrint( msg: String ) = {
println( "trait:" + msg)
}
}
object TraitDemo {
def main( args: Array[ String ] ) : Unit = {
val userService1 = new UserService( )
val userService2 = new UserService( ) with Printer
userService2. myPrint( "hello" )
}
}
特性構築メカニズム-それを読むだけ
1)詳細な文法
特性では、具体的な方法と抽象的な方法を組み合わせることができます。
具象メソッドを抽象メソッドに依存させることができ、抽象メソッドを特性を継承するサブクラスに実装することができます
この特性機能は、実際にはデザインパターン内のテンプレートデザインパターンの具体化です。
2)コードのデモンストレーション
トレイトには構造化コードもあります。つまり、トレイトのどのメソッドにも含まれていないコードです。
トレイトにコンストラクターパラメーターを含めることはできません。各トレイトにはパラメーターのないコンストラクターがあります(コンストラクターパラメーターの欠如がトレイトとクラスの主な違いです)
特性から継承されたサブクラスとその構築メカニズムは次のとおりです。
親クラスのコンストラクターが最初に実行されます。つまり、クラスクラスは左端に配置する必要があります。
トレイトの構成コードが実行された後、複数のトレイトが左から右に順番に実行されます。
トレイトを構築するときは、最初に親トレイトを構築します。複数のトレイトが同じ親トレイトを継承する場合、親トレイトは1回だけ構築されます。
すべてのトレイトが構築された後、サブクラスのコンストラクターが最後に実行されます。
package cn. hanjiaxiaozhi. traitdemo
class Plane {
println( "Plane的主构造方法执行了" )
}
trait Fly{
println( "Fly的构造方法执行了" )
}
trait LowFly extends Fly {
println( "LowFly的构造方法执行了" )
}
trait HighFly extends Fly {
println( "HighFly的构造方法执行了" )
}
class Boeing extends Plane with LowFly with HighFly{
println( "Boeing的构造方法执行了" )
}
object TestTrait3{
def main( args: Array[ String ] ) : Unit = {
val boeing = new Boeing( )
}
}
拡張:Traitはデザインパターンを実装します-それを読むだけです
1)詳細な文法
クラスが複数のトレイトを継承した後、同じメソッドを複数のトレイトで順番に呼び出し、メソッド本体の最後でsuper。メソッド名を実行できます。
複数のトレイトでメソッドを呼び出す場合、右端のトレイトのメソッドが最初に実行され、次に左に順番に実行されてコールチェーンが形成されます。
この機能は非常に強力であり、実際には、デザインパターンにおける責任の連鎖パターンの具体的な実現です。
2)コードのデモンストレーション
テンプレートメソッドのデザインパターン:抽象メソッドと具体的なメソッドの混合使用
package cn. hanjiaxiaozhi. traitdemo
trait Logger {
def log( msg: String )
def info( msg: String ) = log( "INFO:" + msg)
def warn( msg: String ) = log( "WARN:" + msg)
def error( msg: String ) = log( "ERROR:" + msg)
}
class ConsoleLogger extends Logger {
override def log( msg: String ) : Unit = {
println( "按照tarit中的模版实现的log方法" + msg)
}
}
object TemplateMethodDemo {
def main( args: Array[ String ] ) : Unit = {
val logger = new ConsoleLogger
logger. info( "信息日志" )
logger. warn( "警告日志" )
logger. error( "错误日志" )
}
}
責任チェーンのデザインパターン:トレイトコールチェーン
package cn. hanjiaxiaozhi. traitdemo
trait HandlerTrait {
def handle( data: String ) = {
println( "last one" )
}
}
trait SignatureValidHandlerTrait extends HandlerTrait {
override
def handle( data: String ) = {
println( "check signature: " + data)
super . handle( data)
}
}
trait DataValidHandlerTrait extends HandlerTrait {
override
def handle( data: String ) = {
println( "check data: " + data)
super . handle( data)
}
}
class PersonForRespLine( val name: String ) extends DataValidHandlerTrait with SignatureValidHandlerTrait {
def sayHello = {
println( "Hello, " + this . name)
this . handle( this . name)
}
}
object PersonForRespLine {
def main( args: Array[ String ] ) {
val p = new PersonForRespLine( "tom" )
p. sayHello
}
}