第二十章 抽象成员
package SecondWithProgrammingInScala
/**
* 抽象成员
* 不完全定义的类或者特质 ,包含val,var,def方法,type类型
*/
trait Abstract {
//类型成员 : 简化类型参数 ,方便定义
type T
def transform(x: T): T
//表示确定的不会变化的值
val initial: T
//相当于生成了get/set方法
var current: T
}
//实现时候必须要对所有抽象的成员进行实现
class Concrete extends Abstract {
type T = String
override def transform(x: String): String = initial + x
override val initial: String = "hi"
override var current: String = initial
}
//val的初始化 ,如果成员变量是一个表达式 x+3 ,
//在IntTest初始化的时候不会计算表达式 ,initial会被默认为0
trait IntTest {
val initial: Int
val time: Int
require(initial != 0)
def result = time * initial
}
//val的懒加载
object LazyDemo {
println("initial object")
val x = println("initial x")
lazy val y = println("initial y")
}
object AbstractApp {
def main(args: Array[String]): Unit = {
LazyDemo
println
LazyDemo.y
val num = 2
//预初始化
val test1 = new {
val initial = num + 3
} with IntTest {
val time = 2
def print = println(result)
}
test1.print
val testError = new IntTest {
val initial = num + 3
val time = 2
}
}
}
//合理利用抽象类型
trait Food {
def name: String
}
abstract class Animal {
def name: String
type SuitableFood <: Food
def eat(food: SuitableFood) = println(name + "吃" + food.name)
}
class Grass extends Food {
override def name: String = "草"
}
class Cow extends Animal {
override type SuitableFood = Grass
override def name: String = "牛"
}
object AbstractTypeApp {
def main(args: Array[String]): Unit = {
//将抽象类型放在子类中指定 ,更细致的控制
val anima = new Cow
val food = new Grass
anima.eat(food)
}
}
//枚举
object Color extends Enumeration {
val R = "red"
val G = "green"
val B = "blue"
}
第二十一章 隐式转换和隐式参数
隐式转换就像是自动的强制转换类型 ,之前十九章的泛型中 ,一些类型限定/上下界限定/上下文限定等语法 ,其实就是为了简化隐式转换 .
package SecondWithProgrammingInScala
import java.util.{Comparator, RandomAccess}
/**
* 隐式转换和参数
*/
//对一些已有的无法改动的类(如库函数/第三方库) ,扩展自己定义的方法
//通过隐式转换 ,将类A->类B ,类B是具有需要的方法的类
class A {
val name = "ClassA"
}
class B(val name: String) {
def print = println("hello " + name)
}
object Transform {
def main(args: Array[String]): Unit = {
//定义隐式转换将A->B
/**
* 隐式转换和使用对象需要在一个作用域
* 无歧义 ,同时只有一种隐式转换可以调用
* 每次只调用一个隐式转换 ,不能嵌套
* 优先执行显示调用 ,只有无显示方法才会隐式转换
*
* 类似Map(1->"A")中的->也是通过隐式转化 ,转化成Predef.ArrowAssoc ,并调用->方法
*/
implicit def wapper(a: A) = new B(a.name)
//使用a调用他并没有的方法
val a = new A
a.print
//隐式转换还可以通过参数列表传入
def max1[T](a: T, b: T)(implicit cp: Comparator[T]) = {
if (cp.compare(a, b) >= 0) a else b
}
//声明参数并引入
val cp = new Comparator[Int] {
override def compare(a: Int, b: Int) = a - b
}
println(max1(5, 6)(cp))
//直接声明作用域变量
implicit val cp2 = new Comparator[Int] {
override def compare(a: Int, b: Int) = a - b
}
println(max1(5, 6))
}
}