[Scala基础系列 08]Scala继承、抽象类、接口trait以及AOP实现

1.继承

和java一样,scala采用extends关键字继承基类。代码实例如下:

/**
* Created by molyeo on 2015/8/11.
*/
class Person(val name: String, var age: Int) {
  println("The primary constructor of Person")
  val school = "BJU"
  def sleep = "8 hours"
  override def toString = "I am a Person1!"
}

class Worker(name: String, age: Int, val salary: Long) extends Person(name, age) {
  println("This is the subClass of Person, Primary constructor of Worker")
  override val school = "Spark"
  override def toString = "I am a Worker!" + super.sleep
}

object OverrideOperations {
  def main(args: Array[String]) {
    val w = new Worker("Spark", 25, 100000)
    println("School :" + w.school)
    println("Salary :" + w.salary)
    println(w.toString())
  }
}

子类重写基类字段和方法,添加override即可,本程序先调用基类Person的构造函数,然后调用子类Worker的构造函数,并在子类中调用父类的sleep方法,故运行结果如下

The primary constructor of Person
This is the subClass of Person, Primary constructor of Worker
School :Spark
Salary :100000
I am a Worker!8 hours

2.抽象类

抽象类中只用定义字段和相关方法,然后子类实现即可。

class AbstractClassOps{
    var id : Int = _
}
abstract class SuperTeacher(val name : String){
  var id : Int
  var age : Int
  def teach
}

class TeacherForMaths(name : String) extends SuperTeacher(name){

  override var id = name.hashCode()
  override var age = 29
  override def teach{
    println("Teaching!!!")
  }
}

object AbstractClassOps{
  def main(args: Array[String]) {
      val teacher = new TeacherForMaths("Spark")
      teacher.teach
      println("teacher.id" + ":" + teacher.id)
      println(teacher.name + ":" + teacher.age)
  }
}

将输入参数"Spark"的hashcode作为对象的id,故运行结果如下:

Teaching!!!
teacher.id:80085693
Spark:29

3.接口Trait

3.1.传统接口trait

package com.tv189.test

/**
 * Created by molyeo on 2015/8/11.
 */

class UseTrait {

}

trait Logger {
  def log(msg: String)
}

class ConcreteLogger extends Logger with Cloneable {
  override def log(msg: String) = println("Log: " + msg)
  def concreteLog {
    log("It‘s me !!!")
  }
}
object UseTrait extends App {
  val logger = new ConcreteLogger
  logger.concreteLog
}

ConcreteLogger实现了Logger的log方法,故输出结果显而易见:

 log("It‘s me !!!")

3.2.混入对象的trait

与java的interface有明显区别的是,trait可以有具体的方法,如若将上述代码修改如下:

package com.tv189.test

/**
 * Created by molyeo on 2015/8/11.
 */

class UseTrait {

}

trait Logger {
//  def log(msg: String)
  def log(msg: String){}
}

class ConcreteLogger extends Logger with Cloneable {
//  override def log(msg: String) = println("Log: " + msg)
  def concreteLog {
    log("It‘s me !!!")
  }
}

trait TraitLogger extends Logger {
  override def log(msg: String) {
    println(" TraitLogger Log content is : " + msg)
  }
}

object UseTrait extends App {
//  val logger = new ConcreteLogger
//  logger.concreteLog

  val logger=new ConcreteLogger with TraitLogger
  logger.concreteLog

}

则程序输出为:

TraitLogger Log content is : It‘s me !!!

程序实际上是将TraitLogger这个trait混入到具体的对象logger中。

4.多重继承的执行顺序

scala对于多重继承会从左到右进行构造,如果左边的接口已经构建过,则后续的接口不会重复构建,这点和java有很大的不同。如下述程序

package com.tv189.test

/**
 * Created by molyeo on 2015/8/11.
 */

class UseTrait {

}

class Human {
  println("Human")
}

trait TTeacher extends Human {
  println("TTeacher")

  def teach
}

trait PianoPlayer extends Human {
  println("PianoPlayer")

  def playPiano = {
    println("I am playing piano. ")
  }
}

class PianoTeacher extends Human with TTeacher with PianoPlayer {
  override def teach = {
    println("I am training students. ")
  }
}

object UseTrait extends App {
  val t = new PianoTeacher
  t.playPiano
  t.teach
}

其运行结果

Human
TTeacher
PianoPlayer
I am playing piano.
I am training students. 

5.AOP的实现

scala中利用trait可以轻松实现AOP,如下我们在Work类doAction方法的前后打印"Initialization"和"Destroyed"内容

package com.tv189.test

/**
 * Created by molyeo on 2015/8/11.
 */

class UseTrait {

}

//AOP
trait Action {
  def doAction
}

trait TBeforeAfter extends Action {
  abstract override def doAction {
    println("Initialization")
    super.doAction
    println("Destroyed")
  }
}

class Work extends Action {
  override def doAction = println("Working...")
}

object UseTrait extends App {
  val work = new Work with TBeforeAfter
  work.doAction
}

程序输出如下

Initialization
Working...
Destroyed
时间: 2025-01-06 02:40:17

[Scala基础系列 08]Scala继承、抽象类、接口trait以及AOP实现的相关文章

[Scala基础系列 04]Scala基本类型

1.Scala的数值类型 Scala的数值类型与Java类似,他们的范围与Java也是一致的.与Java不同的是,他们都是对象,是相应的数值类的实例.Scala通过富包装(Rich Wrapper)类给这些数值类型提供了强大的支持. 1.1.数值类型 Scala的数值类型和取值范围,见下表. Boolean: true 或者 false Byte: 8位, 有符号(2-7 ~ 27 - 1) Short: 16位, 有符号 (2-15 ~ 215 - 1) Int: 32位, 有符号 (2-31

[Scala基础系列 06]Scala类和对象

1.类和构造函数 Scala中的类,基本概念与其他面向对象语言是一致的,不过在语法上有些不一样的地方.与Java等语言相比,Scala的类语法更简洁,使用起来也更方便. 1.1.类的基本语法 我们先来看一个简单的类定义和使用的代码. class ScoreCalculator { private var total, count = 0 def report(score: Int) { total += score count += 1 } def score = if (count == 0)

[Scala基础系列 07]Scala集合

Scala有一个非常通用,丰富,强大,可组合的集合库:集合是高阶的(high level)并暴露了一大套操作方法.很多集合的处理和转换可以被表达的简洁又可读,但不审慎地用它们的功能也会导致相反的结果.每个Scala程序员应该阅读 集合设计文档:通过它可以很好地洞察集合库,并了解设计动机. 1.数组(Array&ArrayBuffer) 1.1.Array 数组(Array)其实并不在scala.collection包里面,它属于scala包,直接对应于Java的数组,比如,Scala中的Arra

[Scala基础系列 10]Scala泛型、类型边界

1.泛型和类型边界 1.1.上限(upper bounds) 我们先看一个简单的实例,用于判断两个变量中较大的值,其中两个变量的类型均为Int型 package com.tv189.advanced /** * Created by molyeo on 2015/8/12. */ class PairInt(val first: Int, val second: Int) { def bigger = { if (first.compareTo(second) > 0) first else s

[Scala基础系列 03]Scala操作符

1.Scala操作符简介 首先,请记住,Scala没有操作符!也没有通常意义上的表达式.你所见到的类似操作符和表达式的语句,其实是方法(函数),它们只是方法的一种比较直观的写法,可以叫做操作符记法. 1.1.二元操作符(中缀表达式) 二元操作符是最常见的操作符,比如,一个简单的表达式1 + 2.其实,“+”是定义在Int类的一个方法,你完全可以用普通方法调用的写法1.+(2).相应的,其他的方法,比如"Hello".drop(2),也可以用操作符记法,"Hello"

[Scala基础系列 05]Scala控制结构

1.If语句 Scala的If语句可以完成其他语言中If语句,于此同时,if/else通常还有值,可以用来赋值,或者代替三元条件运算符(?:).不过它可以比条件运算符更强大,因为你可以在if-else里面写很复杂的程序块. 1.1.普通的If语句 package com.tv189.foundation /** * Created by molyeo on 2015/7/30. */ object IfCondition { def main(args: Array[String]) { val

[Scala基础系列 02]Scala函数

本文主要内容如下: 变量和不变量 函数和过程 函数的参数 分号 1.变量和不变量 1.1.变量 Scala的变量分两种,var和val.var,即variable,类似于我们在Java等其他语言中接触到的变量,而val,是value,类似于我们在其他语言中用到的不可重新赋值的常量,或者final变量. 为什么会有这种区别,这是由于很多情况下,其实你不需要一个可变的var,尤其在函数式编程中,更为明显.不变性能给程序带来很多便利,因此Scala非常强调不可变(immutable)的概念.关于不可变

第三章:继承/抽象类/接口

继承 在面向对象编程中,有两种截然不同的继承类型,实现继承和接口继承;C#中不支持多重继承,C#类可以派生自另一个类和任意多的接口 实现继承:表示一个类型派生自一个基类型,它拥有该基类型的所有成员字段和函数,在需要给现有类型添加功能或者许多相关类型共享一组重要的公共功能时.这种类型继承非常有用 接口继承:表示一个类型只继承了函数的签名,没有继承任何的实现代码 实现继承virtual/override /// <summary> /// 基类 /// </summary> class

第1节 Scala基础语法:scala中的方法源码分析

val list=List(1,2,3,4) list.reduce((x:Int,y:Int)=>x+y)--->list.reduceLeft((x:Int,y:Int)=>x+y) var first = true var acc:Int = 0 op=(x:Int,y:Int)=>x+y for循环第一次循环:acc=1 first = false第二次循环:acc=op(1,2)=1+2=3第三次循环:acc=op(3,3)=3+3=6第四次循环:acc=op(6,4)=