scala--オブジェクト指向の特性-★★★

  • Java7インターフェース:フィールドと抽象メソッドのみを定義できます
  • Java8インターフェース:フィールドと抽象メソッドを定義し、デフォルトのメソッドを実装できます
  • その場合、Scalaの特性はJava8のインターフェースに似ています
  • それは、抽象メソッドと通常のメソッド(実装されたメソッド)の定義を実行することです。
  • Java 8のインターフェースは、盗用されたScalaの特性です。
  • しかし、トレイトには他にも多くの機能があります

Java8のインターフェース-★

  • Java 8のインターフェースは、JavaによってコピーされたScalaの特性です。
package cn.hanjiaxiaozhi.traitdemo;/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 9:31
 * Desc 演示Java8中的接口
 */
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();//注意:Java8之前接口中的方法只能是抽象方法
    //那么如果有一个需求:要给所有的手机加上一个视频通话的功能
    //Java8之前只能在接口中加一个抽象方法
    //但是只要一加上抽象方法,所有的子类都报错,都得去实现
    //所以Java8中的接口升级是很危险的!尽量避免
    //void video();
    //但是不能因为这个原因就不升级啊!
    //所以Java8的时候Java抄袭Scala的特质trait,
    //允许在接口中定义带有实现的默认方法
    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
​
/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 9:41
 * Desc 演示Scala中的特质-trait,就是Java8中接口的祖宗/原型
 */
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继承/实现trait,第一个用extends,后面如果继承多个用with
//class继承trait之后需要重新/实现抽象方法和抽象字段
class Children(val name: String) extends HelloTrait with MakeFriendsTrait with Cloneable with Serializable {
    
    
  override def sayHello(): Unit = {
    
    
    println("hello "+ name)
  }override val id: Long = 1override 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//hello jack
    jack.makeFriends(tom)
    //hello my name is jack my age is 18 your name is tom
  }
}

特性はクラスを継承できます-理解-★

  • トレイトはクラスを継承することもでき、クラスのすべてのメンバーを継承します
package cn.hanjiaxiaozhi.traitdemo
​
/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 10:19
 * Desc 
 */
class MyUtil {
    
    
  def printMsg(msg:String)={
    
    
    println(msg)
  }
}
//Scala中的trait可以继承class
trait LogUtil extends MyUtil{
    
    
  def log(msg:String) ={
    
    
    //这里也可以写log本身自己的方法逻辑
    //也可以直接调用继承过来的方法
    this.printMsg(msg)
  }
}class Person(val name:String) extends LogUtil{
    
    
  def sayHello()={
    
    
    this.log("hello "+name)
    //Person继承LogUtil,LogUtil继承MyUtil,所以可以直接调用MyUtil中的printMsg
    //this.printMsg(name)
  }
}
object TestTrait2{
    
    
  def main(args: Array[String]): Unit = {
    
    
    new Person("jack").sayHello()
  }
}

特性に混合されたオブジェクト-理解-★

  • オブジェクトをインスタンス化するときに、withキーワードを使用して特性を組み合わせることができるため、オブジェクトに機能を動的に追加できます。
    • val / varオブジェクト名=特性を持つ新しいクラス
    • オブジェクトを作成するときにトレイトを混在させることができ、オブジェクトはトレイトにメソッドを持ちます
    • これはTraitの高度な機能です。理解してください。自分で開発するときに使用することはめったにありません。
package cn.hanjiaxiaozhi.traitdemo
​
/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 10:26
 * Desc 演示对象可以混入Trait
 */
class UserService{
    
    
  
}trait Printer{
    
    
  def myPrint(msg:String) ={
    
    
    println("trait:" + msg)
  }
}object TraitDemo {
    
    
  def main(args: Array[String]): Unit = {
    
    
    val userService1 = new UserService()
    //userService1.myPrint("hello") //错误的,因为UserService中没有myPrint方法//可以在创建对象的时候混入trait,那么该对象就有了trait中的方法
    val userService2 = new UserService() with Printer
    userService2.myPrint("hello")
    //trait:hello}
}

特性構築メカニズム-それを読むだけ

1)詳細な文法

  • 特性では、具体的な方法と抽象的な方法を組み合わせることができます。
  • 具象メソッドを抽象メソッドに依存させることができ、抽象メソッドを特性を継承するサブクラスに実装することができます
  • この特性機能は、実際にはデザインパターン内のテンプレートデザインパターンの具体化です。

2)コードのデモンストレーション

ここに画像の説明を挿入

  • トレイトには構造化コードもあります。つまり、トレイトのどのメソッドにも含まれていないコードです。
  • トレイトにコンストラクターパラメーターを含めることはできません。各トレイトにはパラメーターのないコンストラクターがあります(コンストラクターパラメーターの欠如がトレイトとクラスの主な違いです)
  • 特性から継承されたサブクラスとその構築メカニズムは次のとおりです。
    • 親クラスのコンストラクターが最初に実行されます。つまり、クラスクラスは左端に配置する必要があります。
    • トレイトの構成コードが実行された後、複数のトレイトが左から右に順番に実行されます。
    • トレイトを構築するときは、最初に親トレイトを構築します。複数のトレイトが同じ親トレイトを継承する場合、親トレイトは1回だけ構築されます。
    • すべてのトレイトが構築された後、サブクラスのコンストラクターが最後に実行されます。
package cn.hanjiaxiaozhi.traitdemo
​
/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 10:32
 * Desc 
 */
//Plane飞机类
class Plane {
    
    
  //默认主构造中的代码语句会在Plane类初始化的时候执行
  println("Plane的主构造方法执行了")
}//飞行接口/特征
trait Fly{
    
    
  println("Fly的构造方法执行了")
}
//低空飞行特征
trait LowFly extends Fly {
    
    
  println("LowFly的构造方法执行了")
}
//高空飞行特征
trait HighFly extends Fly {
    
    
  println("HighFly的构造方法执行了")
}//波音飞机类继承Plane飞机类,实现低空飞行和高空飞行特征
class Boeing extends Plane  with LowFly  with HighFly{
    
    
  println("Boeing的构造方法执行了")
}object TestTrait3{
    
    
  def main(args: Array[String]): Unit = {
    
    
    val boeing = new Boeing()
    //Plane的主构造方法执行了 -- 父类的构造器先执行
    //Fly的构造方法执行了     -- 顶级特质的构造器特征再执行
    //LowFly的构造方法执行了  -- 直接继承的特征的构造器特征再执行
    //HighFly的构造方法执行了 -- 直接继承的特征的构造器特征再执行
    //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 {
    
    
  //重写trait中的抽象方法
  override def log(msg: String): Unit = {
    
    
   println("按照tarit中的模版实现的log方法"+msg)
  }
  //具体的方法就相当于直接拿过来了
  //def info(msg:String) = log("INFO:" + msg)
  //def warn(msg:String) = log("WARN:" + msg)
  //def error(msg:String) = log("ERROR:" + msg)
}object TemplateMethodDemo {
    
    
  def main(args: Array[String]): Unit = {
    
    
    val logger = new ConsoleLogger
    logger.info("信息日志")
    logger.warn("警告日志")
    logger.error("错误日志")
  }
}
  • 責任チェーンのデザインパターン:トレイトコールチェーン
package cn.hanjiaxiaozhi.traitdemo
​
//处理trait
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)
  }
}//该类继承DataValidHandlerTrait数据校验trait 和 SignatureValidHandlerTrait签名校验trait
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
    //Hello, tom
    //check signature: tom
    //check data: tom
    //last one
    //这样就实现了一个责任链模式
    //从继承的trati的最右边开始执行调用的方法}
}

おすすめ

転載: blog.csdn.net/qq_46893497/article/details/114042971