Scala 特质类-Trait (七)

Scala trait类
使用方面类似于Java中的Interface接口

特点:

  • 声明特质类时,类的类型为trait
  • 特质类中,可以有抽象成员也可以有具体成员;
  • 特质类在实现时,如果当前类没有父类使用extends关键字class 类名 extends 特质类1 with 特质类2 with 特质类3 ...
  • 特质类在实现时,如果当前类有父类,使用时class 子类名 extends 父类名 with 特质1 with 特质2 ...

定义

package traits

/**
  * 特质类 类似于java的接口
  */
trait Animal {

  // 抽象属性
  var name: String

  // 抽象方法
  def eat
}

实现

// 无父类 extends 特质类
class Dog extends Animal {

  override var name: String = _

  override def eat: Unit = println("dog eating...")
}

object Dog {
  def main(args: Array[String]): Unit = {
    // 多态 接口引用指向实现类
    val a1: Animal = new Dog
    a1.eat
  }
}

class Person

// 有父类  先继承 父类 在混入特质类
class SmallStudent extends Person with Animal {
  override var name: String = _
  override def eat: Unit = println("small student eating ...")
}

带有具体实现的特质类

/**
  * 特质类 类似于java的接口
  */
trait Animal {

  // 抽象属性
  var name: String

  // 抽象方法
  def eat

  // 具体成员
  var age: Int = 0

  // 具体方法
  def sleep: Unit = println("sleeping ....")
}

注意:让特质混有具体行为有一个弊端. 当特质改变时, 所有混入该特质的类都必须重新编译

特质动态混入(mixin)

动态混入(mixin):指在创建单个对象时,可以在不破坏对象声明的前提下,扩展对象的功能

在构造单个对象时, 你可以为它添加特质

  • 特质可以将对象原本没有的方法与字段加入对象中, 功能扩展
  • 无需修改类声明定义,扩展类的功能,灵活简便
  • 如果特质和对象改写了同一超类的方法, 则排在右边的先被执行
package traits.mixin

/**
  * 特质类 类似于java的接口
  */
trait Animal {

  // 抽象属性
  var name: String

  // 抽象方法
  def eat

  // 具体成员
  var age: Int = 0

  // 具体方法
  def sleep: Unit = println("sleeping ....")
}

/**
  * 普通类
  */
class Person

class SmallStudent extends Person {

}

object SmallStudent {
  def main(args: Array[String]): Unit = {
    // 创建普通对象时,具备动物基本特征
    // 动态混入(mixin)
    val s1 = new SmallStudent() with Animal{

      override var name: String = _

      override def eat: Unit = println("小学生吃辣条...")
    }

    println(s1.age)   // 0
    s1.name = "狗蛋"
    println(s1.name) // 狗蛋
    s1.eat  // 小学生吃辣条...
    s1.sleep // sleeping ....
  }
}

this别名

scala中this代表的是当前类,可以给this起别名,通常命名为self

package traits

class Cat {
  // this别名语法
  self =>

  var name:String = _

  def this(name:String){
    this()
    // this.name = name
    self.name = name
  }
  println(this == self)
}

object Cat{
  def main(args: Array[String]): Unit = {
    val cat = new Cat()
  }
}
外部类和内部类的应用
class Outer {
  outer =>
  val v1 = "here"

  class Inner {
    inner =>
    val v1 = "-------------"
    println(outer.v1) // 用outer表示外部类,相当于Outer.this
    println(inner.v1)
  }
}
object Outer {
  def main(args: Array[String]): Unit = {
    val outer = new Outer()
    val inner = new outer.Inner

    /**
      * here
      * -------------
      */
  }
}

self-type(自类型)

强制混入: 类在声明时需要混入特质类或者抽象类

package traits

trait Fruit {
  var name: String
}

trait Apple {
  // 强制混入Fruit特质类
  my: Fruit =>

  def eat= println(my.name)
}

class RedApple extends Apple with Fruit{
  override var name: String = "红苹果"
}

object RedApple{
  def main(args: Array[String]): Unit = {
    new RedApple().eat
  }
}

应用程序对象

Java中,每一个程序都需要从一个对象的main 方法开始,Scala中也同样,每一个程序都必须从一个对象的main 方法开始,这个方法的类型为Array[String]。Java中可以使用Junit 测试方法,Scala中有一个类似的特质类,实现类似的功能

App 特质类扩展自另一个特质类DelayedInit,有该特质的类其初始化方法都会被挪到delayedInit方法中,App特质的main方法捕获到命令行参数,调用delayedInit方法,并且还可以根据要求打印出程序执行所用的时间

package function

import scala.util.Properties
object HighOrderFunction3 extends App {
  println(args.length)

    var arr = Array[String]("Hello Hadoop","Hello Kafka")

  //显示程序执行时间  注意导包
  Properties.setProp("scala.time","true")
  arr
      .flatMap(_.split("\\s"))
      .filterNot(_.equalsIgnoreCase("kafka"))
      .map((_,1L))
      .groupBy(_._1)
      .map(t2 => (t2._1,t2._2.length))
      .foreach(println)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值