代码4.1

class Student{
     //声明成员变量,这里成员变量必须初始化
     private var age = 18   //私有成员变量,初始化为18
     val name="Scala"    //定义属性name
     def increase(): Unit = { age+= 1} //方法默认是公有的
     def current(): Int = {age}
}

代码4.2

//创建Student类的对象
scala> val student= new Student

//通过Student类的对象调用Student类的方法
scala> student.increase() //也可以不用圆括号,写成student.increase

//直接输出调用Student类方法的结果
scala> println(student.current)
19

代码4.3

class Student{
	private var age = 18  
	val name="Scala"    
	def increase(): Unit = { age+= 1} 
		def current(): Int = {age}
	}

	object TestStudent_01 {
		def main(args: Array[String]) {
		val student= new Student
		student.increase()
		println(student.current)
	}
}

代码4.4

public class Student{
      private int age;
      public int getAge(){return age;} //getter方法
      public void setAge(int age){this.age=age;} //setter方法
}

代码4.5

class Student{
private var privateAge= 0  //私有成员变量
def age = privateAge      //获得成员变量的值
      def age_=(newAge: Int){   //设置成员变量的值
            if (newAge>18) 
			privateAge = newAge  //只有提供的新值大于18,才允许修改
      }
}

代码4.6

class Student {
    private var age= 18  //age用来存储学生的年纪
    private var name = ""  //表示学生的名字
	private var classNum = 1  //ClassNum用来表示学生的班级

    def this(name: String){  //第一个辅助构造函数
        this()  //调用主构造函数this
        this.name = name //给name赋值
     }

    def this (name: String, classNum: Int){  //第二个辅助构造函数
        this(name)  //调用前一个辅助构造函数
        this.classNum = classNum
	}

	def increase(step: Int): Unit = { age += step}  //增加年龄
	def current(): Int = {age}
	def info(): Unit = {
		printf("Name:%s and classNum is %d\n",name,classNum)
	}
}

代码4.7

object TestStudent_02{

     def main(args:Array[String]){
        val myStudent1 = new Student  //主构造函数

		//第一个辅助构造函数,学生名字设置为ZhangSan
		val myStudent2 = new Student("ZhangSan") 

		//第二个辅助构造函数,学生名字设置为LiSi,班级为75班
        val myStudent3 = new Student("LiSi",75)

        myStudent1.info  //显示学生信息
		myStudent1.increase(1)     //设置步长  
        printf("Current age is: %d\n",myStudent1.current) //显示学生年纪

        myStudent2.info  //显示学生信息
        myStudent2.increase(2)     //设置步长  
        printf("Current age is: %d\n",myStudent2.current) //显示学生年纪

        myStudent3.info  //显示学生信息
        myStudent3.increase(3)     //设置步长  
        printf("Current age is: %d\n",myStudent3.current) //显示学生年纪
    }
}

代码4.8

class Student(val name: String, val classNum: Int) {  //参数列表放在类名后面
    private var age = 18  //age用来存储学生年纪的起始值    
    def increase(step: Int): Unit = {age += step}
    def current(): Int = {age}
    def info(): Unit = {printf("Name:%s and classNum is %d\n",name,classNum)}
}

object TestStudent_03{
 	def main(args:Array[String]){  
          val myStudent = new Student("ZhangSan",67)
          myStudent.info  //显示学生信息
          myStudent.increase(1)  //设置步长  
          printf("Current age is: %d\n",myStudent.current) //显示学生年纪 
	}
}


代码4.9

//通过object关键字定义单例对象TestStudents_01
scala> object TestStudents_01{
private var studentNum=0
//定义newStuNum方法,将学号加1,返回新的学号studentNum
def newStuNum={
studentNum+=1
studentNum
} 
}
defined object Students

//直接通过单例对象名称访问其成员方法
scala> TestStudents_01.newStuNum
res0: Int = 1

//单例对象中的成员变量状态随程序执行而改变
scala> TestStudents_01.newStuNum
res1: Int = 2

代码4.10

object TestStudents_02{
	private var studentNum=0
	//定义newStuNum方法,将学号加1,返回新的学号studentNum
	def newStuNum={
		studentNum+=1
		studentNum
	} 

	//通过main方法作为程序的入口
	def main(args:Array[String]){
		println("New num is "+Students.newStuNum)
	}
}

代码4.11

//定义类Students
class Students{   
     val id = Students.newStuId() //调用了伴生对象中的方法
     private var number =0
     def aClass(number: Int) { this.number= number}
}

//定义类Students的伴生对象object Students
object Students {  
     private var StuId = 0  //学号
     def newStuId() = {
          StuId +=1
          StuId 
     }

     def main(args: Array[String]){
		  //直接调用伴生对象Students的方法newStuId
          println(Students.newStuId)
          //再次调用newStuId方法,学号StuId在加1
          println(Students.newStuId)
     }
}

代码4.12

//普通类成员变量在定义时必须显式初始化
scala> class Phone{
        var phoneBrand: String=_
      }
defined class Phone

//不显式初始化成员变量会报错,提示Phone类应该被声明为abstract
scala> class Phone{
        var phoneBrand: String
      }
<console>:11: error: class Phone needs to be abstract, since variable phoneBrand is not defined
(Note that variables need to be initialized to be defined)
       class Phone{
             ^

代码4.13

//成员变量如果不显式初始化,则将类声明为抽象类,通过abstract关键字来定义
scala> abstract class Phone{
        var phoneBrand: String
      }
defined class Phone

代码4.14

scala> abstract class Phone{
        var phoneBrand: String //抽象类中的抽象成员变量
        var price:Int=0 //抽象类中的具体成员变量
        def info() //抽象类中的抽象方法
        def greeting() =println("Welcome to use phone!") //抽象类中的具体方法
      }
defined class Phone

代码4.15

//定义抽象类
scala> abstract class Phone(var phoneBrand:String,var price:Int){
        def info:Unit
      }
defined class Phone

//使用抽象类,创建匿名类对象
scala> val p=new Phone("HuaWei",5000){
    //重写抽象内中的抽象方法 
	override def info:Unit=println(s"Phone($phoneBrand,$price)")
       }
p: Phone = $anon$1@225e09f0

scala> p.info
Phone(HuaWei,5000)


代码4.16

abstract class Phone{   //是抽象类,不能直接被示例化
     val phoneBrand: String  //成员变量没有初始化值,就是一个抽象成员变量
     def info()  //抽象方法,不需要使用abstract关键字
     def greeting() {  //具体方法
		println("Welcome to use phone!") 
	 }
}

代码4.17

/*父类中包含抽象成员变量时,子类如果为普通类则必须将该成员变量初始化,否则子类也应声明为抽象类*/
scala> class XiaoMi extends Phone
<console>:12: error: class XiaoMi needs to be abstract, since:
it has 2 unimplemented members.
/** As seen from class XiaoMi, the missing signatures are as follows.
 *  For convenience, these are usable as stub implementations.
 */
  def info(): Unit = ???
  val phoneBrand: String = ???

       class XiaoMi extends Phone
             ^

//在子类中对父类中的抽象成员变量及抽象方法进行初始化,使用override关键字
scala> class Apple extends Phone{
          override val phoneBrand:String="Apple"
          override def info:Unit=println("Welcome to use iphone!")
     }
defined class Apple

//也可以省略override关键字
scala> class Apple extends Phone{
       val phoneBrand:String="Apple"
       def info:Unit=println("Welcome to use iphone!");
     }
defined class Apple

代码4.18

class Apple extends Phone{

     //重写父类成员变量,可以使用override关键字。
     override val phoneBrand = "Apple"     

  	 //重写父类的抽象方法时,不需要使用override关键字,不过,如果加上override编译也不报错
	 def info() {
		printf("This is a/an %s phone. It is expensive", phoneBrand)
	 }   

     //重写父类的非抽象方法,必须使用override关键字
     override def greeting() {
     	println("Welcome to use Apple Phone!")
     }

}

class HuaWei extends Phone { 

	//重写父类成员变量,需要使用override关键字,否则编译会报错
	override val phoneBrand = "HuaWei"   

	//重写父类的抽象方法时,不需要使用override关键字,不过,如果加上override编译也不会报错
	def info() {
		printf("This is a/an %s phone. It is useful.", phoneBrand)
	} 

    //重写父类的非抽象方法,必须使用override关键字
	override def greeting() {
		println("Welcome to use HuaWei Phone!")
	}
}


代码4.19

abstract class Phone{   
     val phoneBrand: String 
     def info()
     def greeting() {
	 	println("Welcome to use phone!")
	 }
}

class Apple extends Phone{
	override val phoneBrand = "Apple"  
	def info() {
		printf("This is a/an %s phone. It is expensive.\n", phoneBrand)
	} 
	override def greeting() {
		println("Welcome to use Apple Phone!")
	} 
}

class HuaWei extends Phone { 
	override val phoneBrand = "HuaWei" 
    def info() {
		printf("This is a/an %s phone. It is useful.\n", phoneBrand)
	} 
	override def greeting() {
		println("Welcome to use HuaWei Phone!")
	} 
}

object MyPhone {  
	def main(args: Array[String]){
        val myPhone1 = new Apple()
        val myPhone2 = new HuaWei ()
        myPhone1.greeting()
        myPhone1.info()       
        myPhone2.greeting()
        myPhone2.info()
    }
}

代码4.20

//定义Phone类,带主构造函数
class Phone(var phoneBrand:String,var price:Int){
	//类中执行语句会在调用主构造函数时执行
	println("执行Phone类的主构造函数")
}

//定义Apple类,继承自Phone类,同样也带主构造函数
class Apple(phoneBrand:String,price:Int)extends Phone(phoneBrand,price){
	//类中执行语句会在调用主构造函数时执行
	println("执行Apple类的主构造函数")
}

object TestPhone_01{
	def main(args:Array[String]){
		//创建子类对象时,先调用父类的主构造函数,然后调用子类的主构造函数
		new Apple("iphone",5400)
	}
}


代码4.21

class Phone(var phoneBrand:String,var price:Int){
	//对父类Any中的toString方法进行重写
	override def toString=s"Phone($phoneBrand,$price)"
}

class Apple(phoneBrand:String,price:Int,var place:String)extends Phone(phoneBrand,price){
	//对父类Phone中的toString方法进行重写
	override def toString=s"Apple($phoneBrand,$price,$place)"
}

Object TestPhone_02{
	def main(args:Array[String]){
		//调用Apple类自身的toString方法返回结果
		println(new Apple("iphone",5400,"Shenzhen"))
	}
}

代码4.22

Object TestPhone_03{

    //定义父类Phone
	class Phone(var phoneBrand:String,var price:Int){
		def buy():Unit=println("buy() method in Phone") //buy方法,无参数
		//compare方法,参数为Phone类型
		def compare(p:Phone):Unit=println("compare() method in Phone")
	}

    //定义子类Apple
	class Apple( phoneBrand:String,price:Int) extends Phone(phoneBrand,price){
		private var AphoneNo:Int=0
		//重写父类compare方法
		override def compare(p:Phone):Unit={
			println("compare() method in Apple")
			println(this.phoneBrand+" is compared with "+p.phoneBrand)
		}
	}

    //定义子类HuaWei
	class HuaWei(phoneBrand:String,price:Int) extends Phone(phoneBrand,price){
		private var HphoneNo:Int=0
        //重写父类buy方法
		override def buy():Unit=println("buy() method in HuaWei")
		//重写父类compare方法
		override def compare(p:Phone):Unit={
			println("compare() method in HuaWei")
			println(this.phoneBrand+" is compared with "+p.phoneBrand)
		}
	}

    //运行入口
	def main(args: Array[String]){
		val p1:Phone=new HuaWei("huawei",4500)
		val p2:Phone=new Apple("iphone",6400)
		/*p1实际上引用的是HuaWei类型的对象,HuaWei类对父类中buy方法进行了重写,因此它调用的是重写后的方法*/
		p1.buy()
		//compare方法参数类型为Phone,调用的是HuaWei类重写后的compare方法
		p1.compare(p2)
		println("-----------------------------")
		/*p2引用的是Apple类型的对象,Apple类未对父类中的buy方法进行重写,因此它调用的是继承自父类的buy方法*/
		p2.buy()
		//p2.compare(p1)传入的实际类型是HuaWei,调用的是Apple类重写后的compare方法
		p2.compare(p1)
    }
}

代码4.23

//定义一个特质PhoneId
trait PhoneId{
     var id: Int
     def currentId(): Int     //定义一个抽象方法
}

代码4.24

class ApplePhoneId extends PhoneId{  //使用extends关键字
     override var id = 10000  //Apple手机编号从10000开始
     def currentId(): Int = {id += 1; id}  //返回手机编号
 }

 class HuaWeiPhoneId extends PhoneId{  //使用extends关键字
     override var id = 20000  //HuaWei手机编号从20000开始
     def currentId(): Int = {id += 1; id}  //返回手机编号
 } 

代码4.25

trait PhoneId{
    var id: Int
    def currentId(): Int     //定义了一个抽象方法
}

class ApplePhoneId extends PhoneId{  //使用extends关键字
   	override var id = 10000  //Apple手机编号从10000开始
   	def currentId(): Int = {id += 1; id}  //返回手机编号
 }

 class HuaWeiPhoneId extends PhoneId{ //使用extends关键字
	override var id = 20000  //HuaWei手机编号从20000开始     
	def currentId(): Int = {id += 1; id}  //返回手机编号
 } 

 object TraitPhone_01 { 
    def main(args: Array[String]){
        val myPhone1 = new ApplePhoneId()       
        val myPhone2 = new HuaWeiPhoneId ()
        printf("My first PhoneId is %d.\n",myPhone1.currentId)
		printf("My second PhoneId is %d.\n",myPhone2.currentId)
    }
}

代码4.26

trait PhoneId{
   var id: Int
   def currentId(): Int     //定义了一个抽象方法
}

trait PhoneGreeting{
   def greeting(msg: String) { println(msg) }  
}

object TraitPhone_02{ 
   	//使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
	class ApplePhoneId extends PhoneId with PhoneGreeting{
    	override var id = 10000  //Apple手机编号从10000开始
    	def currentId(): Int = {id += 1; id}  //返回手机编号
	}

	//使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
	class HuaWeiPhoneId extends PhoneId with PhoneGreeting{ 
    	override var id = 20000  //HuaWei手机编号从10000开始
    	def currentId(): Int = {id += 1; id}  //返回手机编号
	} 

	def main(args: Array[String]){
		val myPhone1 = new ApplePhoneId()       
       	val myPhone2 = new HuaWeiPhoneId ()
        myPhone1.greeting("Welcome my first phone.")
        printf("My first PhoneId is %d.\n",myPhone1.currentId)        
        myPhone2.greeting("Welcome my second phone.")
        printf("My second PhoneId is %d.\n",myPhone2.currentId)
    }
}

代码4.27

scala> trait Phone{
        println("Phone")
        def phone1(msg:String):Unit 
        def phone2(msg:String):Unit=println(msg)
      }
defined trait Phone

scala> abstract class Phone{
        println("Phone")
        def phone1(msg:String):Unit
        def phone2(msg:String):Unit=println(msg)
      }
defined class Phone

代码4.28

//Phone为trait
scala> trait Phone{
       println("Phone")
       def phone1(msg:String):Unit
       def phone2(msg:String):Unit=println(msg)
      }
defined trait Phone

//使用extends关键字混入Phone
scala> class Apple extends Phone{
       def phone1(msg:String):Unit=println("phone1:"+msg)
      }
defined class Apple

scala> val p=new Apple
Phone
p: Apple = Apple@718ad3a6

scala> p.phone1("Apple extends Phone trait")
phone1:Apple extends Phone trait

代码4.29

//将Phone定义为抽象类
scala> abstract class Phone{
       println("Phone");
       def phone1(msg:String):Unit;
       def phone2(msg:String):Unit=println(msg);
      }
defined class Phone

//通过extends关键字扩展类Phone,实现继承
scala> class Apple extends Phone{
        def phone1(msg:String):Unit=println("phone1:"+msg)
      }
defined class Apple

scala> val p=new Apple
Phone
p: Apple = Apple@7d6019d5

scala> p.phone1("Apple extends abstract class Phone")
phone1:Apple extends abstract class Phone


代码4.30

//定义一个普通类
scala> class A{
        val msg:String="msg"
       }
defined class A

//trait B继承自类A
scala> trait B extends A{
        def print()=println(msg)
      }
defined trait B

scala> new B{}.print()
msg

代码4.31

scala> abstract class Phone(val msg:String)
defined class Phone

scala> trait Phone(val msg:String)
<console>:1: error: traits or objects may not have parameters
trait Phone(val msg:String)
         ^

代码4.32

scala> trait A
defined trait A

scala> trait B
defined trait B

//类可以混入多个trait
scala> class C extends A with B
defined class C

代码4.33

scala> trait A{
        def print:Unit
     }
defined trait A

scala> trait B1 extends A{
        var B1="trait B1";
        override def print=println(B1);
      }
defined trait B1

scala> trait B2 extends A{
        var B2="trait B2";
        override def print=println(B2);
      }
defined trait B2

scala> class C extends B1 with B2
defined class C

scala> val c=new C
c: C = C@6c2f8ecb

//使用的是trait B2中的print方法
scala> c.print
trait B2

代码4.34

scala> trait A{
         val a="Trait A";
         def print(msg:String)=println(msg+":"+a);
      }
defined trait A


scala> trait B1 extends A{
         val b1="Trait B1";
         override def print(msg:String)=super.print(msg+":"+b1);
      }
defined trait B1

scala> trait B2 extends A{
         val b2="Trait B2";
         override def print(msg:String)=super.print(msg+":"+b2);
      }
defined trait B2

scala> class C extends B1 with B2
defined class C

scala> new C().print("print method in")
print method in:Trait B2:Trait B1:Trait A

代码4.35

package cn{
	package spark{
          package packagetest{
               abstract class Phone{
                   def use:Unit
               }
    	           //用于单元测试
               package tests{
                    class Suite
               }
               //用于功能实现
               package impls{
 	               class Apple extends Phone{
                        def use=println("welcome to use iphone")
				   }
			   }
		 }
	}
}



代码4.36

//定义一个包对象phone
package object phone{
   //定义属于包对象phone的属性defaultName
   val defaultName="XiaoMi"
}

package phone{
   class phone{
   		//package phone包里面的类可直接引用defaultName
		var name=defaultName
   }
}

代码4.37

//将java.util.HashMap重命名为JavaHashMap
import java.util.{ HashMap =>JavaHashMap }
import scala.collection.mutable.HashMap
object RenameUsage {
     def main(args: Array[String]): Unit ={ 
  		 val javaHashMap =new JavaHashMap[String, String]()
  		 javaHashMap.put("Spark", "excellent")
		 javaHashMap.put("MapReduce", "good")
  		 for(key <- javaHashMap.keySet().toArray){
			 println(key+":"+javaHashMap.get(key))
		 }
	     val scalaHashMap=new HashMap[String,String]
		 scalaHashMap.put ("Spark", "excellent")
		 scalaHashMap.put ("MapReduce", "good")
		 scalaHashMap.foreach(e=>{
  			 val (k,v)=e
 			 println(k+":"+v)
		 })
	 }
}

代码4.38

//通过HashMap=>_,类便被隐藏起来
import java.util.{ HashMap=>_,_ }
import scala.collection.mutable.HashMap
object ClassHiddenUsage{
	def main(args:Array[String]): Unit={
		//HashMap更无歧义地指向scala.collection.mutable.HashMap
		val scalaHashMap =new HashMap[String,String]
		scalaHashMap.put("Spark","excellent" )
		scalaHashMap.put("MapReduce","good")
		scalaHashMap.foreach(e =>{
			val (k,v)=e
            println(k+":"+v)
		})
	}
}