Open justtreee opened 6 years ago
其实与Java或C++的写法差不多,但更简洁。最基本的写法:
class Counter {
private var value = 0 //必须初始化
def increment() = { value += 1}
def current() = value
}
val myCnt = new Counter //或Counter()
myCnt.increment()
println(myCnt.current())
//1
对于私有属性,使用getter和setter方法进行获取和设置。这与Java或C++一致。在Scala中
每个类都有一个主要的构造器,这个构造器和类定义交织在一起,它的参数直接成为类的字段。主构造器执行类体中所有的语句。
辅助构造器是可选的,叫做this
本章直接靠练习学习吧。
class Counter {
private var value = 0 //必须初始化
def increment() = {
if((value+1).isValidInt)
value += 1
}
def current() = value
}
val myCnt = new Counter //或Counter() for(_ <- 1 to Int.MaxValue) myCnt.increment() println(myCnt.current())
//2147483647
2. 编写一个BankAccount类,加入deposit和withdraw方法,和一个只读的balance属性。
```scala
class BankAccount(val banlance : Int){
def deposit = {
println("depodit")
}
def withdraw = {
println("withdraw")
}
}
val a = new BankAccount(200)
a.deposit
a.withdraw
println(a.banlance)
//depodit
//withdraw
//200
class Time(val vh:Int, val vm:Int)
{
private val hrs = vh
private val min = vm
def hours = hrs
def minutes = min
def before(other: Time) : Boolean = {
other.hours > this.hours || (other.hours == this.hours && other.minutes > this.minutes)
}
}
val t = new Time(23,10) println(t.before(new Time(23,11)))
//true
4. 重新实现前一个练习中的Time类,将内部呈现改成自午夜起的分钟数(介于0到24x60-1之间)。不要改变公有接口。也就是说,客户端代码不应因你的修改而受影响。
```scala
class Time(val vh:Int, val vm:Int)
{
private val hrs = vh
private val min = vm
def hours = hrs
def minutes = min
def before(other: Time) : Boolean = {
other.hours > this.hours || (other.hours == this.hours && other.minutes > this.minutes)
}
def total = (this.hours * 60 + this.minutes)
}
val t = new Time(23,10)
println(t.before(new Time(23,11)))
class Person
{
private var page = 0
def age_= (v :Int) {//age_= 的=前面不能有空格
if (v < 0)
page = 0
else
page = v
}
def age = page
}
val p = new Person()
p.age = -1
println(p.age)
//0
7. 编写一个Person类,其主构造器接受一个字符串,该字符串包含名字、空格和姓,如new Person(“Fred Smith”)。提供只读属性firstName和LastName。
```scala
class Person(val name : String)
{
val firstName = name.split(" ")(0)
val lastName = name.split(" ")(1)
}
val p = new Person("Fred Smith")
println(p.firstName)
println(p.lastName)
//Fred
//Smith
创建一个Car类,以只读属性对应制造商、型号名称、型号年份以及一个可读写的属性用于车牌。提供四组构造器。每一个构造器都要求制造商和型号名称为必填。型号年份以及车牌为可选,如果未填,则型号年份设置为-1,车牌设置为空字符串。你会选择哪一个作为你的主构造器?为什么?
class Car(val maker : String, val name : String)
{
private var privateModel = -1
var licence = ""
def this(maker : String, name : String, model : Int) {
this(maker, name)
this.privateModel = model
}
def this(maker : String, name : String, licence : String) {
this(maker, name)
this.licence = licence
}
def this(maker : String, name : String, model : Int, licence : String) {
this(maker, name, model)
this.licence = licence
}
def model = privateModel
}
val car = new Car("Tom Smith", "tst", 2017, "GG6666") println(car.model)
在本章中,会学到何时使用Scala的object
语法结构,在需要某个类的单个实例,或者向想为其他值或函数找一个可以挂靠的地方是,就会用到它。
每个Scala程序都必须从一个对象的main方法开始,这个方法的类型为Array[String]=>Unit
:
object Hello{
def main(args : Array[String]): Unit = {
println("hello")
}
}
本章主要也是以练习学习为主。
object Conversions{
def inchesToCentimeters(v: Double) = {
v * 2.54
}
def gallonsToliters(v: Double) = {
v * 3.785
}
def milesToKilometers(v: Double) = {
v * 1.609
}
}
println(Conversions.inchesToCentimeters(3.3))
//8.382
2. 前一个练习不是很面向对象,提供一个通用的超类UnitConversion并定义扩展该超类的InchesToCentimeters、GallonsToLiters和MilesToKilometers对象。
```scala
abstract class UnitConversion{
def convert(v : Double) : Double
}
object inchToCentimeters extends UnitConversion{
override def convert(v: Double): Double = v*2.54
}
object gallonToLiters extends UnitConversion{
override def convert(v: Double): Double = v*3.7854
}
object milesToKilometers extends UnitConversion{
override def convert(v: Double): Double = v*1.6093
}
println(inchToCentimeters.convert(3))
println(gallonToLiters.convert(3.3))
println(milesToKilometers.convert(3.3))
//7.62
//12.491819999999999
//5.310689999999999
class Point(val x : Double, val y : Double){
}
object Point{
def apply(x:Double,y:Double) = new Point(x, y)
}
val p = Point(3.3,4.4)
println(p.x)
//3.3
5. 编写一个Scala应用程序,使用App特质,以反序打印命令行参数,用空格隔开。
```scala
object TestApp extends App
{
println(args.reverse.mkString(","))
}
object Enum extends Enumeration{
val Club = Value(0, "♣")
val Diomand = Value(1, "♦")
val Heart = Value(2, "♥")
val Spade = Value(3, "♠")
}
object Test extends App{
for (c <- Enum.values)
println(c.toString)
}
//♣ //♦ //♥ //♠
7. 编写一个函数,检查某张牌的花色是否为红色。
```scala
object Enum extends Enumeration{
val Club = Value(0, "♣")
val Diomand = Value(1, "♦")
val Heart = Value(2, "♥")
val Spade = Value(3, "♠")
}
object Test extends App{
for (c <- Enum.values){
println(c.toString)
println(check(c))
}
def check(value: Enum.Value) = {
if(value == Enum.Heart || value == Enum.Diomand)
true
else
false
}
}
//♣
//false
//♦
//true
//♥
//true
//♠
//false
object RGBCube extends Enumeration {
val R = Value(0xff0000)
val G = Value(0x00ff00)
val B = Value(0x0000ff)
val RG = Value(0xffff00)
val RB = Value(0xff00ff)
val GB = Value(0x00ffff)
val RGB = Value(0xffffff)
val BLACK = Value(0x000000)
}
object Test extends App{
for (c <- RGBCube.values) {
printf("#%06x\n", c.id)
}
}
//#0000ff
//#00ff00
//#00ffff
//#ff0000
//#ff00ff
//#ffff00
//#ffffff
第四章 映射和元组
1. 映射
Scala中映射是对偶的集合,也就是两个值构成的组,这两个值不一定是一个类型的。
2. 元组
映射是对偶的集合,对偶是元组(tuple)的最简单形式——元组是不同类型的值的聚集。
拉链操作:
练习
val in = new Scanner(new File("/text.txt")) val map = new scala.collection.mutable.HashMap[String, Int]() while(in.hasNext()){ val str = in.next() map(str) = map.getOrElse(str,0) + 1 } println(map.mkString(","))
//(alpha) -> 1,PageRank -> 1,Collaborative -> 1 .......................
val in = new Scanner(new File("/text.txt")) val map = scala.collection.immutable.SortedMap[String, Int]() var m = map //不可变(val)映射 while(in.hasNext()){ val str = in.next() m += (str -> (m.getOrElse(str,0) + 1)) //添加一对映射 } println(m.mkString(","))
//(alpha) -> 1,(e.g., -> 3,API -> 1,API. -> 1............................
//(2,1,3)