下面的代碼包含了基本的scala的文法内容。包括:判斷,循環代碼片段,方法定義,調用。 虛拟類,繼承,接口,case,package,單例模式
package org.exinglo.scala
class learnscala {
}
object test{
val variable1 = "this is my first scala variable"
def func1(): string = "hello world" //不帶參數的函數被調用時,可以不加括号
def func2(who : string): string = { return "hello world " + who}
def func3 = (x : int, y : int) => x + y //這是個匿名函數的寫法,調用的時候,func3(1,2)
//這裡給了y一個預設值,如果使用者傳過來,那就用使用者的
def func4(x: int)(y : int = 1): int = x + y //加脂法的寫法,調用時, func4(1)(2)
// * 代表多個參數的意思,比如 printeverychar("c","b", "a"),可以傳遞多個string
def printeverychar(c : string*) = {
c.foreach(x => println(x))
}
def main(args : array[string]) {
println(variable1)
for(i <- 0 to 10 if i%2 == 0){
println("i is a even number: " + i)
}
for(i <- 0 until 10){
println("")
var (n, r) = (10, 0)
while(n > 0){
n = n - 1
val p = new person //這裡可以省略括号
println("information about person:" + p.name + " " + p.age) //如果p.name沒有指派的話,這裡會顯示為null
class person{ //類預設是public類型的
var name : string = _ //會生成setter和getter方法
val age = 10 //隻會生成getter方法
private[this] val gender = "male" //無法在下面的main方法通路gender,這個屬性隻能在對象内部通路
//生成對象時 val p = new person2("java", 10)
//如果參數聲明時不帶val或者var,那麼這個變量相當于内部變量,比如 class person(name: string) 這裡的name就無法在外部被通路到了
class person2(val name : string, val age : int){//括号中的内容屬于主構造器,其中的參數會作為類的屬性存在
println("this is the person2's constructor")//這裡屬于預設構造器,生成對象時,會執行這句話
var gender : string = _ //這裡要求初始化
//附屬構造器必須叫做this,必須首先調用已經存在的子構造器或者其他附屬構造器
def this(name : string, age : int, gender : string){
this(name, age)//必須調用預設的構造器,=
this.gender = gender
//成成student對象的時候,會先列印父類構造器的列印語句,然後但因student類的語句
class student(val grade : int, name : string, age : int) extends person2(name, age) {
println("this is the subclass of person, grade is:" + grade)
override def tostring() : string = {""} //覆寫父類的方法,一定要加上override關鍵字,其實不僅僅是父類的方法,覆寫父類的var val都要加上override
package org.exinglo.abstractandtrait
class abstractandtrait {
//抽象類(abstract class)
//• 類的⼀一個或者多個⽅方法沒有沒完整的定義, 當然也可以沒有任何抽象方法。
// 對于子類覆寫父類的非抽象方法,一定要override關鍵字
//• 聲明抽象⽅方法不需要加abstract關鍵字,隻需要不寫⽅方法體
//• ⼦子類重寫⽗父類的抽象⽅方法時不需要加override
//• ⽗父類可以聲明抽象字段(沒有初始值的字段)
//• ⼦子類重寫⽗父類的抽象字段時不需要加override
abstract class personx{
def speak
val name:string
val age:int
class student extends personx{
//必須要實作抽象方法,像這種不寫等于号的情況,表示傳回類型是unit類型
def speak{
println("speak")
val name:string = ""
val age:int = 3
trait logger{
def log(msg:string)
//這裡的trait consolelogger可以不實作父類的方法,也可以覆寫父類的方法實作,也可以實作父類的虛方法
trait consolelogger extends logger{
def log(msg:string){
println("save money:" + msg)
//因為是覆寫上級的方法,必須使用override關鍵字
trait messagelogger extends consolelogger{
override def log(msg:string){
println("save money to account:" + msg)
//如果一個類沒有繼承其他的類,實作的第一個trait隻能用extends,其他的用with關鍵字
class test extends consolelogger{
def test{
log("hellp")
abstract class account{
def save
class myaccount extends account with consolelogger{
def save{
log("100")
object run extends app{
//這裡是一個很好玩的地方,單獨給一個對象混入了一個特質trait,并且這個特質與類的定義繼承的特質有沖突
//列印出來的是messagelogger中的log方法
val acc = new myaccount with messagelogger
acc.save
class applytest(val msg:string) {
def apply() = msg
println(msg)
object applytest{
//下面是apply方法的最常用的方式
def apply() = new applytest("object calls new")
//object的方法相當于java中的靜态方法
def static{
println("i am a static method")
object basic extends app{
//類似于下面,嗲用object的方法
applytest.static
val t = new applytest("new")
println(t())
//據說下面這樣可以調用object applytest中的apply方法,但是我的編譯器總是報錯
//後來發現是object的apply方法一開始聲明沒有加上小括号造成的,如def apply = xxxx
val tt = applytest()
println(tt())
// applytest()是調用object的apply方法
// val t = new applytest(); t() 調用的是class applytest的apply方法
/*
* package com.xyz{
* //-------------
* package spark
* }
* }
*
* { //這裡隻在程式塊中可見
* import com.yyy
*
* import java.util.{hashmap =>javahashmap} //定義一個别名
* package aa.bb.cc.dd
* class xxx{
* private[dd] def variable = {} //根據private[]中指定的不同,可見範圍不同
* */
class packageandcase {
object basict extends app{
val value = 3
val result = value match{
case 1 => "one"
case 2 => "two"
case _ => "some other number"
val result2 = value match{
case i if i == 1 => "one"
case i if i == 2 => "two"
case _ => "other number"
def t(obj : any) = obj match{
case x:int => println("int")
case s:string => println("string")
case _ => println("unkonwn type")
t(2)
}