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;
}

  

 懶加載 java

//懶加載
//定義的文本順序不用多考慮,由於初始化是按需的
//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;
}

  

抽象類型ide

錯誤寫法ui

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方法,由於參數類型不一樣
}

  

正確寫法blog

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){}
}
相關文章
相關標籤/搜索