Kotlin Programming 2020 Fall - Lecture 7
===
###### tags: `Kotlin`
This lecture intends to cover the materials in Chapter 12.
## Define a Class
A class may contain
1. Constructors and initialization blocks
2. Properties
3. Functions
4. Nested & inner classes (not in this lecture)
5. Object declaration (not in this lecture)
```kotlin
import java.util.Scanner
class Score {
var point = 0
fun gradePoint() = when (point) {
in 90..100 -> 4.3
in 85..89 -> 4.0
in 80..84 -> 3.7
in 77..79 -> 3.3
in 73..76 -> 3.0
in 70..72 -> 2.7
in 67..69 -> 2.3
in 63..66 -> 2.0
in 60..62 -> 1.7
in 50..59 -> 1.0
else -> 0.0
}
fun grade() = when (point) {
in 90..100 -> "A+"
in 85..89 -> "A"
in 80..84 -> "A-"
in 77..79 -> "B+"
in 73..76 -> "B"
in 70..72 -> "B-"
in 67..69 -> "C+"
in 63..66 -> "C"
in 60..62 -> "C-"
in 50..59 -> "D"
in 1..49 -> "E"
else -> "X"
}
fun isPass(isGraduate: Boolean = false): Boolean {
return (!isGraduate && point >= 60) || point >= 70
}
fun isFail(isGraduate: Boolean = false) = !isPass(isGraduate)
}
fun main() {
val scanner = Scanner(System.`in`)
print("What is your score? ")
val yourScore = Score()
yourScore.point = scanner.nextInt()
println("Your grade is ${yourScore.grade()}.")
println("Your grade point is ${yourScore.gradePoint()}.")
println("Pass as a graduate student: ${yourScore.isPass(true)}")
println("Fail as an undergraduate student: ${yourScore.isFail(false)}")
}
```
## Class Functions
+ `this`
+ Can also be defined outside of `class` block
```kotlin
import java.util.Scanner
class Score {
var point = 0
fun gradePoint() = when (point) {
in 90..100 -> 4.3
in 85..89 -> 4.0
in 80..84 -> 3.7
in 77..79 -> 3.3
in 73..76 -> 3.0
in 70..72 -> 2.7
in 67..69 -> 2.3
in 63..66 -> 2.0
in 60..62 -> 1.7
in 50..59 -> 1.0
else -> 0.0
}
fun grade() = when (point) {
in 90..100 -> "A+"
in 85..89 -> "A"
in 80..84 -> "A-"
in 77..79 -> "B+"
in 73..76 -> "B"
in 70..72 -> "B-"
in 67..69 -> "C+"
in 63..66 -> "C"
in 60..62 -> "C-"
in 50..59 -> "D"
in 1..49 -> "E"
else -> "X"
}
}
fun Score.isPass(isGraduate: Boolean): Boolean {
return (!isGraduate && this.point >= 60) || this.point >= 70
}
fun Score.isFail(isGraduate: Boolean) = !this.isPass(isGraduate)
fun main() {
val scanner = Scanner(System.`in`)
print("What is your score? ")
val yourScore = Score()
yourScore.point = scanner.nextInt()
println("Your grade is ${yourScore.grade()}.")
println("Your grade point is ${yourScore.gradePoint()}.")
println("Pass as a graduate student: ${yourScore.isPass(true)}")
println("Fail as an undergraduate student: ${yourScore.isFail(false)}")
}
```
## Class Properties
+ Can be declared as `val` or `var`
+ Getter: the function to report the value of the property.
+ Setter: the function to update the value of the property (for `var` only).
+ `field`: an identifier for the property in its getter and setter.
```kotlin
var point = 0
get() = field
set(value) = when {
value < 0 -> field = 0
value > 100 -> field = 100
else -> field = value
}
```
+ Default getter and setter
+ The getter / setter of the data type of `val` / `var`
+ Computed properties
```kotlin
val passOrFail: Boolean
get() = point >= 60
```
Sample code
```kotlin
import java.util.Scanner
class Score {
var point = 0
get() = field
set(value) = when {
value < 0 -> field = 0
value > 100 -> field = 100
else -> field = value
}
fun gradePoint() = when (point) {
in 90..100 -> 4.3
in 85..89 -> 4.0
in 80..84 -> 3.7
in 77..79 -> 3.3
in 73..76 -> 3.0
in 70..72 -> 2.7
in 67..69 -> 2.3
in 63..66 -> 2.0
in 60..62 -> 1.7
in 50..59 -> 1.0
else -> 0.0
}
fun grade() = when (point) {
in 90..100 -> "A+"
in 85..89 -> "A"
in 80..84 -> "A-"
in 77..79 -> "B+"
in 73..76 -> "B"
in 70..72 -> "B-"
in 67..69 -> "C+"
in 63..66 -> "C"
in 60..62 -> "C-"
in 50..59 -> "D"
in 1..49 -> "E"
else -> "X"
}
fun isPass(isGraduate: Boolean = false): Boolean {
return (!isGraduate && point >= 60) || point >= 70
}
fun isFail(isGraduate: Boolean = false) = !isPass(isGraduate)
}
fun main() {
val scanner = Scanner(System.`in`)
print("What is your score? ")
val yourScore = Score()
yourScore.point = scanner.nextInt()
println("Your score is ${yourScore.point}")
println("Your grade is ${yourScore.grade()}.")
println("Your grade point is ${yourScore.gradePoint()}.")
println("Pass as a graduate student: ${yourScore.isPass(true)}")
println("Fail as an undergraduate student: ${yourScore.isFail(false)}")
}
```
## Visibility
+ Modify the visibility of properties, functions, getters, setters.
+ `public`
+ Default. Free for all.
+ `private`
+ Only visible in the class
+ `protected`
+ Same as `private` with visible in subclasses.
+ `internal`
+ Visible in the same module
+ Compiled together
+ In the same IntelliJ IDEA project
## Constructing Instances
### Primary Constructor
+ A constructor is like a function that initializes the instance.
+ The arguments of the primary constructor is defined after the class name.
+ The primary constructor `init` blocks.
```kotlin
import java.util.Scanner
class Score(_point: Int) {
var point = 0
get() = field
set(value) = when {
value < 0 -> field = 0
value > 100 -> field = 100
else -> field = value
}
init {
point = _point
}
fun gradePoint() = when (point) {
in 90..100 -> 4.3
in 85..89 -> 4.0
in 80..84 -> 3.7
in 77..79 -> 3.3
in 73..76 -> 3.0
in 70..72 -> 2.7
in 67..69 -> 2.3
in 63..66 -> 2.0
in 60..62 -> 1.7
in 50..59 -> 1.0
else -> 0.0
}
fun grade() = when (point) {
in 90..100 -> "A+"
in 85..89 -> "A"
in 80..84 -> "A-"
in 77..79 -> "B+"
in 73..76 -> "B"
in 70..72 -> "B-"
in 67..69 -> "C+"
in 63..66 -> "C"
in 60..62 -> "C-"
in 50..59 -> "D"
in 1..49 -> "E"
else -> "X"
}
fun isPass(isGraduate: Boolean = false): Boolean {
return (!isGraduate && point >= 60) || point >= 70
}
fun isFail(isGraduate: Boolean = false) = !isPass(isGraduate)
}
fun main() {
val scanner = Scanner(System.`in`)
print("What is your score? ")
val yourScore = Score(scanner.nextInt())
println("Your score is ${yourScore.point}.")
println("Your grade is ${yourScore.grade()}.")
println("Your grade point is ${yourScore.gradePoint()}.")
println("Pass as a graduate student: ${yourScore.isPass(true)}")
println("Fail as an undergraduate student: ${yourScore.isFail(false)}")
}
```
#### Practice
+ Task 1
Change functions `Score.grade()` and `Score.gradePoint()` to properties.
+ Task 2
Change the getter of `point` to automatically adjust the score with the formula $f(x)=\lceil 10\sqrt{x}\rceil$