Scala学习笔记--抽象成员

时间:2023-03-09 04:15:57
Scala学习笔记--抽象成员
package com.evor.test1
class Test1 {
} object Test1{
def main(args:Array[String]):Unit = { //类参数和抽象字段的初始化顺序并不一致
//抛出异常的原因:RationalTrait初始化的时候,denonArg仍然为0
/*
val r1 = new RationalTrait{
val numerArg=50;
val denomArg=60;
}
*/ //解决方案:预初始化字段。在调用超类之前初始化子类字段
val r2 = new {
val numerArg=50;
val denomArg=60;
}with RationalTrait
}
} //解决方案:预初始化字段。在调用超类之前初始化子类字段
object twoThirds extends {
val numerArg = 2;
val denomArg = 3;
}with RationalTrait //解决方案:预初始化字段。在调用超类之前初始化子类字段
//类定义中的预初始化字段
class RationalClass (n:Int,d:Int) extends{
val numerArg = n;
val denomArg = d;
}with RationalTrait{
def + (that:RationalClass) = new RationalClass (
numer *that.denom +that.numer*denom, denom*that.denom)
} trait RationalTrait{
val numerArg:Int ;
val denomArg:Int ;
require(denomArg!=0);
private val g = gcd(numerArg,denomArg)
val numer = numerArg/g
val denom = denomArg/g private def gcd(a:Int,b:Int):Int={
if(b==0) a
else gcd(b,a%b)
} override def toString = numer+"/"+denom;
}

  

懒加载

//懒加载
//定义的文本顺序不用多考虑,因为初始化是按需的
//g将在numer和denom之前完成初始化
trait RationalTrait{
val numerArg:Int ;
val denomArg:Int ; lazy val numer = numerArg/g
lazy val denom = denomArg/g lazy private val g = {
require(denomArg!=0);
gcd(numerArg,denomArg)
} private def gcd(a:Int,b:Int):Int={
if(b==0) a
else gcd(b,a%b)
} override def toString = numer+"/"+denom;
}

  

抽象类型

错误写法

class Food

abstract class Animal{
def eat(food:Food)
} class Grass extends Food
class Cow extends Animal{
override def eat(food:Grass){} //cow类的eat方法不能重写animal类的eat方法,因为参数类型不同
}

  

正确写法

class Food

abstract class Animal{
type SuitableFood <:Food //类型有上界约束 Food
def eat(food:SuitableFood)
} class Grass extends Food
class Cow extends Animal{
type SuitableFood = Grass
override def eat(food:Grass){}
}