小记--------scala-面向对象之Trait

trait基础知识
将trait作为接口使用
    在scala中的Trait是一种特殊的概念
首先我们可以将Trait作为接口来使用, 此时的Trait就与java中的接口非常类似
在triat中可以定义抽象方法,就与抽象类中的抽象方法一样,只要不给出方法的具体实现即可
    类可以使用定义抽象方法, 就与抽象类中的抽象方法一样,只要不给出方法的具体实现即可。
    类可以使用extends关键字集成trait,
  注意:这里不是implement,而是extends,在scala中没有implement的概念,无论继承类还是trait,统一都是extends。
    类继承trait后,必须实现其中的抽象方法,实现时不需要使用override关键字
    scala不支持对类进行多继承,但是支持多重继承trait,使用with关键字即可
 
注意: scala中的trait可不是只定义抽象方法, 还可以定义具体方法, 此时trait更像是包含了通用工具方法的东西
   
在trait中定义具体方法
    有个专有的名词来形容这种情况, 就是说trait的功能混入了类。 例如spark源码中,使用了trait定义了通用的日志打印方法
    
在trait中定义具体字段
    scala中的trait可以定义具体的field, 此时 继承trait的类就自动获得了trait中定义的field
    但是这种获取field的方式与继承class是不同的 ;
    如果是继承class获取的field,实际是定义在父类中的;
    而继承trait获取的field,就直接被添加到了类中。
 
 
在trait中定义抽象字段
    在scala中的trait可以定义抽象field ,而trait中的具体方法则可以基于抽象field来编写。
     但继承trait的类, 则必须覆盖抽象field,提供具体的值
 
trait高级知识
为实例对象混入trait
    有时我们可以在创建类的对象时, 指定该对象混入某个trait,这样就只有这个对象混入该trait的方法,而类的其他对象没有
 
trait调用链
    在scala中支持让类继承多个trait后,一次调用多个trait中的同一个方法,只要让多个trait的同一个方法中,在最后都执行 supper.方法
    在类中调用多个trait中都有的这个方法时,首先会从最右边的trait的方法开始执行,然后依次往左执行,形成一个调用链条
    这种特性非常强大,其实就相当于设计模式中的责任链模式的一种具体实现依赖
 
 
在trait和覆盖抽象方法
    在trait中,是可以覆盖父trait的抽象方法的,
    但是覆盖时,如果使用了super.方法的代码,则无法通过编译。 因为super.方法会去调用父trait的抽象方法,此时子trait的该方法还是会被认为是抽象的
    此时如果要通过编译,就得给子trait的方法加上abstract override修饰
 
 
混合使用trait的具体方法和抽象方法    
    在trait中,可以混合使用具体方法和抽象方法
    可以让具体方法依赖于抽象方法,而抽象方法则放到继承trait的类中去实现
    这种trait其实就是设计模式中的模板设计模式的体现
 
 
trait的构造机制
    在scala中,trait也是由构造函数的,也就是trait中的,不包含在任何方法中的代码(也就是constructor了)
    而继承了trait的类的构造机制如下:
     1.父类的构造函数执行
    2.trait的构造代码执行,多个trait从左到右依次执行
    3.构造trait时会先选构造父trait,如果多个trait继承同一个父trait,则父trait只会构造依次
    4.所有trait构造完毕后,子类的构造函数执行
 
trait字段的初始化
    在scala中,trait是没有接收参数的构造函数的,这是trait与class唯一区别,但是如果需求就是能够对field进行初始化,只能使用scala中非常特殊的一种高级特性--提前定义
 
让trait继承类
    在scala中,trait也可以继承 自class, 此时这个class会继承trait和其所有的父类
 
 

猜你喜欢

转载自www.cnblogs.com/yzqyxq/p/12682821.html