scala中trait注意事项

前言

在scala中的抽象类能有的成员, 那么特质(trait)都可有

  1. 属性
  2. 方法
  3. 抽象属性
  4. 抽象方法
  5. 构造器(主/辅)

与抽象类的区别
抽象类只能单继承,trait可以多混入!

class A extends t1 with t2 with t3...

叠加冲突

由于一个类可以混入(mixin)多个trait,且trait中可以有具体的属性和方法,若混入的特质中具有相同的方法(方法名,参数列表,返回值均相同),必然会出现继承冲突问题。冲突分为以下两种

第一种,一个类(Sub)混入的两个trait(TraitA,TraitB)中具有相同的具体方法,且两个trait之间没有任何关系,解决这类冲突问题,直接在类(Sub)中重写冲突方法

第二种,一个类(Sub)混入的两个trait(TraitA,TraitB)中具有相同的具体方法,且两个trait继承自相同的trait(TraitC),及所谓的“钻石问题”,解决这类冲突问题,Scala采用了特质叠加的策略。
这个解决方案是给TraintA和TraitB找一个共同的父TraitC,在C里面也声明相同的冲突方法。最后会调用的是特质叠加的最后一个trait里面的冲突方法!
所谓的特质叠加是指将多个trait全部叠加到一起!
下面一个示例来说明!

trait Ball {
  def describe(): String = {
    "ball"
  }
}

trait Color extends Ball {
  override def describe(): String = {
    "blue-" + super.describe()
  }
}

trait Category extends Ball {
  override def describe(): String = {
    "foot-" + super.describe()
  }
}

class MyBall extends Category with Color {
  override def describe(): String = {
    "my ball is a " + super.describe()
  }
}

object TestTrait {
  def main(args: Array[String]): Unit = {
    println(new MyBall().describe())
  }
}

运行结果!

在这里插入图片描述

一般来说调用顺序是 class MyBall extends Category with Color 从右至左,所以color先被调用!而在color中使用了super来调用方法!注意这里调用的会是兄弟trait里面的describe方法!而不是父类的!一定要注意!!!!
如果想让color使用super调用父类的describe方法需要做下面的改写!

class MyBall extends Category with Color {
  override def describe(): String = {
    "my ball is a " + super[Ball].describe()
  }
}

总结

冲突的方法最终使用的是最后叠加的那个!!!

  • 初始化的是, 一个trait最多初始化一次
  • 初始化的时候是从父开始, 从左
  • super.describe()不是真正的找父类, 而是按照叠加的顺序向前找
  • super[Ball].describe() 明确指定这个super应该是哪个类

特质继承类注意事项

class M
class A{
    def foo() = {
        println("A... foo")
    }
}


trait B extends A{
    def eat() = {
        println("B ... eat")
        foo()
    }
}
// extends 要么是A要么A的子类
class C extends A with B with M

这里会报错!因为类只能单继承!M是一个类,与A没有关系,C先继承了A那么如果混入M则M必须是A的子类!所以
将M extends A之后则编译才可以通过!

总结

混入时必须注意类之间的关系!看extends后面的类!他来限制后面with中的class!

动态叠加

可以在new对象时with一些trait
例如

new C() with trait A with trait B.......

总结

trait的主构造器为无参构造器!
缺省的(没有加val或者var)变量作为参数时,这个参数看作一个不可变的局部变量!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值