• scala之旅-核心语言特性【特性】(七)


    特性用于类之间的接口和属性共享。它们跟java8中的接口有些类似【注:这里官方说的很准确,类似于java8的接口,而不是java7及之前的接口。因为trait同时可以声明抽象方法,也可以实现抽象方法。相当于是java接口的default的一个推广使用。】。类和伴生对象可以继承特性,但是特性不能被实例化,因此也不会有构造参数。

    定义特性

    一个最简单的特性可以用一个 trait 关键字和一个标志符表示:

    trait HairColor

    特性在泛型和抽象方法中尤为凸显优势

    trait Iterator[A] {
      def hasNext: Boolean
      def next(): A
    }

    继承特性 Iterator[A] 需要一个类型A ,并且实现hasNext和next 方法

    使用特性

    使用关键字 extends 来继承一个特性。然后实现特性的任何抽象成员时需要加上 override 关键字

    trait Iterator[A] {
      def hasNext: Boolean
      def next(): A
    }
    
    class IntIterator(to: Int) extends Iterator[Int] {
      private var current = 0
      override def hasNext: Boolean = current < to
      override def next(): Int = {
        if (hasNext) {
          val t = current
          current += 1
          t
        } else 0
      }
    }
    
    
    val iterator = new IntIterator(10)
    iterator.next()  // returns 0
    iterator.next()  // returns 1

    这里的 IntIterator 使用一个 形参to 作为一个上边界, 继承Iterator[Int] 意味着使用 next 方法时必须返回一个Int 类型

    子类型化

    当需要一个给定的特性时,可以用这个特性的子类型代替。

    import scala.collection.mutable.ArrayBuffer
    
    trait Pet {
      val name: String
    }
    
    class Cat(val name: String) extends Pet
    class Dog(val name: String) extends Pet
    
    val dog = new Dog("Harry")
    val cat = new Cat("Sally")
    
    val animals = ArrayBuffer.empty[Pet]
    animals.append(dog)
    animals.append(cat)
    animals.foreach(pet => println(pet.name))  // Prints Harry Sally

    特性 Pet 有一个抽象属性name, Cat和Dog 通过结构体具体地实现了。 在最后一行,我们调用 pet.name之前,所有子类型必须实现特性 Pet.

  • 相关阅读:
    docker学习记录
    TCP/IP基础介绍
    JS对select操作
    js中删除table里所有行
    端口
    js中定时器的使用
    ASP.NET程序中常用的三十三种代码
    NHibernate学习(转)
    条面向对象设计的经验原则(转)
    客户端等select和input控件
  • 原文地址:https://www.cnblogs.com/zhouwenyang/p/13859216.html
Copyright © 2020-2023  润新知