/** * ex 1 * * Improve the Counter class in Section 5.1, “Simple Classes and Parameterless Methods,” * on page 55 so that it doesn’t turn negative at Int.MaxValue. * */ classCounter{ privatevar value = 0// You must initialize the field defincrement(): Either[String, Int] = { // if(value == Int.MaxValue){ if (value == 3) { Left("hi, reach the sky already..") } else { value += 1 Right(value) } } // Methods are public by default defcurrent() = value }
print the result
1 2 3 4 5 6 7
println("ex 1==========") val cnt = newCounter println(cnt.increment()) println(cnt.increment()) println(cnt.increment()) println(cnt.increment())
got :
1 2 3 4 5
ex 1========== Right(1) Right(2) Right(3) Left(hi, reach the sky already..)
/** * Write a class Time with read-only properties hours and minutes and a method * before(other: Time): Boolean * that checks whether this time comes before the other. * A Time object should be constructed as new Time(hrs, min), where hrs is in * military time format (between 0 and 23). * * @param h * @param min */ classTime(private val h: Int, private val min: Int) {
defhour: Int = h defminute: Int = min
defbefore(other: Time): Boolean ={ if(h == other.h){ return min < other.min } h < other.h }
defbefore2(other: Time) : Boolean = h * 60 + min < other.h * 60 + other.min }
test:
1 2 3 4 5 6 7
println("Time is: " + time.hour + ":" + time.minute)
ex 3============== Time is: 1:30 true false true false
ex 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/** * * Reimplement the Time class from the preceding exercise so that the internal representation is the number * of minutes since midnight (between 0 and 24 × 60 – 1). Do not change the public * interface. That is, client code should be unaffected by your change. * * @param h * @param min */ classTime2(private val h: Int, private val min: Int) { privateval mins: Int = h * 60 + min
defhour: Int = h defminute: Int = min
defbefore(other: Time2) : Boolean = mins < other.mins }
test:
1 2 3 4 5 6
println("ex 4==============") val time2 = newTime2(1, 30) println("Time is: " + time2.hour + ":" + time2.minute)
/** * * Make a class Student with read-write JavaBeans properties name (of type String) and id (of type Long). * What methods are generated? (Use javap to check.) * Can you call the JavaBeans getters and setters in Scala? Should you? */ classStudent{ @BeanProperty var name: String = ""
@BeanProperty var id: Long = 0 }
classStudent2(@BeanProperty var name : String, @BeanProperty var id : Long)
test:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
println("ex 5==============") val st = newStudent st.setId(124) st.setName("hello") println(st.id) println(st.name)
val st2 = newStudent2("hello",123) println(st2.id) println(st2.name) st2.setName("world") st2.setId(345) println(st2.id) println(st2.name)
xwei mtvl15397a13f ~ workspace … scala-2.12 classes chapt5 master 4???? $ ls Exercises$.class Exercises$Student.class Exercises$Time2.class Exercises$BankAccount.class Exercises$Student2.class Exercises$delayedInit$body.class Exercises$Counter.class Exercises$Time.class Exercises.class xwei mtvl15397a13f ~ workspace … scala-2.12 classes chapt5 master 4???? $ javap -private Exercises\$Student Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 Warning: Binary file Exercises$Student contains chapt5.Exercises$Student Compiled from "Exercises.scala" public class chapt5.Exercises$Student { private java.lang.String name; private long id; public java.lang.String name(); public void name_$eq(java.lang.String); public long id(); public void id_$eq(long); public long getId(); public java.lang.String getName(); public void setId(long); public void setName(java.lang.String); public chapt5.Exercises$Student(); } xwei mtvl15397a13f ~ workspace … scala-2.12 classes chapt5 master 4???? $ javap -private Exercises\$Student2 Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 Warning: Binary file Exercises$Student2 contains chapt5.Exercises$Student2 Compiled from "Exercises.scala" public class chapt5.Exercises$Student2 { private java.lang.String name; private long id; public java.lang.String name(); public void name_$eq(java.lang.String); public long id(); public void id_$eq(long); public long getId(); public java.lang.String getName(); public void setId(long); public void setName(java.lang.String); public chapt5.Exercises$Student2(java.lang.String, long); }
ex 6
1 2 3 4 5 6 7 8 9
/** * * In the Person class of Section 5.1, “Simple Classes and Parameterless Methods,” on page 55, * provide a primary constructor that turns negative ages to 0. * @param age */ classPerson(var age: Int = 0){ if(age < 0 ) age = 0 }
test:
1 2 3 4 5 6
println("ex 6==============") val p = newPerson(5) println(p.age)
/** * Write a class Person with a primary constructor that accepts a string containing a first name, * a space, and a last name, such as new Person("Fred Smith"). Supply read-only properties * firstName and lastName. Should the primary constructor * parameter be a var, a val, or a plain parameter? Why? * * @param name */ classPerson2(name: String) { val firstName = name.split(" ")(0) val lastName = name.split(" ")(1)
/** * * Make a class Car with read-only properties for manufacturer, model name, and model year, * and a read-write property for the license plate. Supply four constructors. * All require the manufacturer and model name. Optionally, model year and license plate can * also be specified in the constructor. If not, the model year is set to -1 and the license * plate to the empty string. Which constructor are you choosing as the primary constructor? Why? * * @param manufacture * @param modelName * @param modelYear * @param licence */ classCar(val manufacture: String, val modelName: String, val modelYear: Int = -1, val licence: String = "") { defthis(manufacture: String, modelName: String, license: String) { this(manufacture, modelName, -1, license) }
public Exercises$Car(String manufacture, String modelName, int modelYear, String licence) {} }
ex 10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * * Consider the class * * class Employee(val name: String, var salary: Double) { * def this() { this("John Q. Public", 0.0) } * } * * Rewrite it to use explicit fields and a default primary constructor. Which form do you prefer? Why? * */ classEmployee{ val name : String = "John Q. Pbulic" val salary : Double = 0.0
public Exercises$Employee3(String n, double s) {} }
compare Employee2 and Employe3, looks like only 2 has a auxiliary constructor.
test:
1 2 3 4 5 6 7
println("ex 10==============") val e = newEmployee println(e) val e1 = newEmployee2("abc", 10000) println(e1) val e2 = newEmployee3("def", 200000) println(e2)
got:
1 2 3 4
ex 10============== Employee(John Q. Pbulic, 0.0) Employee2(abc, 10000.000000) Employee3(def, 200000.000000)