1 改进Counter类,让它不要在大于Int.maxValue时变为负数
增加一个判断语句
private var value = 0
def increment() { if (value < Int.MaxValue) value += 1 }
def current() = value
2 写一个BankAccount类,加入deposit和withdraw方法,和一个只读的balance属性
//val 只有getter,没有setter,depotit/withdraw报错,访问不到
val balance: Double = 0
def deposit(money: Double) { balance += money }
def withdraw(money: Double) { balance -= money }
3 定义一个Time类,加入只读属性hours和minutes
另外还有一个检测时间是否早于另一个时间的方法,before(other:Time):Boolean
Time对象以new Time(hrs,min)方式构建,其中0
class Time {
var hours: Int = 0
var mintues: Int = 0
def getHours = hours
def getMinutes = mintues
def this(hrs: Int, min: Int) {
this()
if (hrs <= 23 && hrs >= 0) {
hours = hrs; mintues = min
}
}
def before(other: Time): Boolean = {
if (other.getHours == hours) other.getMinutes > mintues
else other.getHours > hours
}
}
4 重新实现Timer类,内部呈现改成字午夜起的分钟数(介于1-24*60) ,不改变公有接口,也就是说,客户端不因你的修改而受到影响
var hours: Int = 0
var mintues: Int = 0
var mins = 0
// def getHours = hours
// def getMinutes = mintues
def getMins = mins
def this(hrs: Int, min: Int) {
this()
if (hrs <= 23 && hrs >= 0) {
// hours = hrs; mintues = min
mins = hrs * 60 + min
}
}
def before(other: Time): Boolean = {
getMins > other.getMins
}
}
5 创建一个Student类,加入可读写的JavaBeans属性name(类型为String)和id(类型为Long)。有哪些方法被生产?(用javap查看。)你可以在Scala中调用JavaBeans的getter和setter方法吗?应该这样做吗?
class Student(@BeanProperty var name: String, @BeanProperty var id: Long) {
}
object se {
def main(args: Array[String]): Unit = {
var s1 = new Student("Tom", 200)
println(s1.getName())
println(s1.getId())
}
}
共生成9个方法,主构造器+每个字段两对setter/getter(scala+javabean)
输出:Tom,200,证明可调用
6 在5.2节的Person类中加一个主构造器,将负年龄换为0
class Person(var privateage: Int) {
//主构造器的范围:类体中除了方法,构造器,字段均为
if (privateage < 0) privateage = 0
}
7 编写一个Person类,其主构造器接受一个字符串,该字符串包含名字,空格和姓,如new Person(“Fred Smith”)。提供只读属性firstName和lastName。主构造器参数应该是var,val还是普通参数?为什么?
使用普通参数,不属于Person要求的字段
class Person(name: String) {
val firstName: String = name.split(" ")(0)
val lastName: String = name.split(" ")(1)
def getFirst = firstName
def getLast = lastName
}
8 创建一个Car类,以只读属性对应制造商,型号名称,型号年份以及一个可读写的属性用于车牌。提供四组构造器。每个构造器fc都要求制造商和型号为必填。型号年份和车牌可选,如果未填,则型号年份为-1,车牌为空串。你会选择哪一个作为你的主构造器?为什么?
//主构造器包括所有字段
//通过val控制属性为只读
//车牌为可读写,因此主构造器中可有可无,不过设在主构造器中代码量要少
class Car(val Producter: String, val types: String, val year: Int, var num: String) {
def this(Producter: String, types: String) {
this(Producter, types, -1, "")
}
def this(Producter: String, types: String, num: String) {
this(Producter, types, -1, num)
}
def this(Producter: String, types: String, year: Int) {
this(Producter, types, year, "")
}
}
9 在Java,C#或C++重做前一个练习。Scala相比之下精简多少?
public class Car2 {
private String Producter;
private String types;
private String num = "";
private int year = -1;
public Car2(String producter, String types, String num, int year) {
super();
this.Producter = producter;
this.types = types;
this.num = num;
this.year = year;
}
}
Java中只定义字段与主构造器,代码量就已经接近
如果加上其它三个构造器,getter/setter,代码量会加大3倍左右,scala确实很简便
10 考虑如下的类
class Employ(val name:String,var salary:Double){
def this(){this(“John Q. Public”,0.0)}
}
重写该类,使用显示的字段定义,和一个缺省主构造器。你更倾向于使用哪种形式?为什么?
class Employee {
//字段显示定义,个人认为就是直接定义在类体
val name: String = ""
var salary = 0.0
def this(name: String, salary: Double) {
this()
this.salary = salary
// this.name=name //报错
// 如果想给name赋值,只能将name设置为var,但设置为var,就会变为可读写
// 因此,设立主构造器时,尽量把只读的放进主构造器中
}
}