前言
day04(day04-scala学习之数组、映射(Map)、元组(Tuple)),我们学习了scalascala的数组、映射(Map)、元组(Tuple),今天开始进入scala的面向对象特性的学习,今天学习scala中类的定义、属性的getter和setter方法、类的构造器、类的apply方法。
scala面向对象的基本概念
scala面向对象的概念和java中的面向对象的定义是一样的,它也是把数据及对数据的操作方法放在一起,作为一个相互依存的整体(对象)。scala中面向对象的也是java页向对象的三大特征:封装、继承、多态。
scala中定义类
scala中定义类和在java中定义类差不多,不同的是scala中的class关键字前是没有修饰符的。
/**
* 定义一个学生类
* @author sjr
* @version 1.0
*/
class Student {
//定义学生属性
private var name:String = "Tom"
private var age:Int = 20
//定义getter\setter函数
def getName():String = name
def setName(name:String):Unit ={
this.name = name
}
}
属性的getter和setter方法
当定义属性是private时,scala会自动为其提供getter和setter函数,但是scala提供的函数名与属性名是一样的。
如下是一个小实例:
class Student {
//定义学生属性
private var name:String = "Tom"
//不手动定义getter和setter方法
}
//运行使用的main函数,是不能放到class中的,要放到object
object Student{
def main(args: Array[String]): Unit = {
//创建一个对象
val student = new Student
//访问属性,使用getter方法
println(student.name)
//使用setter修改name属性的值
student.name = "SJR"
}
}
基于scala的getter、setter方法机制,scala中只要定义了属性,都是能被外面查看及修改的。但是如果我想让我的属性是只读的(只能查看,不能修改),或者我想让我的属性完全私有(不允许外面查看及修改),这要怎么办?
1. 属性只读:把属性定义为常量(val)
定义属性:private var money:Int = 1000 希望money只能查看(只有get方法),不允许修改(没有set方法)。
办法:将其定义为常量private val money:Int = 1000
2. 属性完全私有:使用this关键字
private[this]的用法:该属性只属于该对象私有,就不会生成对应的set和get方法。如果这样,就不能直接调用。
scala中类的构造器
scala中的构造器分两种:主构造器、辅助构造器
主构造器:和类声明在一块的,一个类只有一个主构造器。像如下在定义类的同时就定义了主构造器。
//构造器,定义成绩的属性
class Course(var courseNmae:String,var grade:Int){
}
辅助构造器:可以有多个,通过this关键字实现。
//如下的类的声明就包含了主构造器了
class Student3(var name:String,var age:Int){
//属性
private var grade:Int = 66
/**
* 辅助构造器必须调用一个构造器,
* 这个调用的构造器可以是主构造器,也可以是其它的辅助构造器,使用this关键字来调。
*/
def this(age:Int){
//调用主构造器
this("Tom",18)
println("这是第一个辅助构造器")
}
def this(){
//调用其它的辅助构造器。
this(20)
println("这是第二个辅助构造器")
}
}
object Student3{
def main(args: Array[String]): Unit = {
//后推前快捷键 ctrl + alt + 空格
//使用主构造器实例化对象
val plus = new Student3("plus",18)
//使用辅助构造器实例化类
//第一次运行辅助构造器,里面会调用主构造器
val student1 = new Student3(20)
//第一次运行第一个辅助构造器,里面会调用第二个辅助构造器,然后运行打印
val student2 = new Student3()
}
}
scala中的object对象
scala中没有static关键字的,在object中所有成员都是静态的,如果object名字和类的名字是相同的,那么它是伴生类,如果有一些需要定义静态的成员,可以定义在object伴生类中。在Object中一般可以为伴生类做一些初始化等操作。
/**
* 实现单例模式
*/
object CreitCard {
//定义一个变量保存信用卡的卡号 private [this] 代表不会自动生成set get 方法
private[this] var creditCarNumber = 0
//定义一个生产卡号的函数
def generateCCNumver():Long ={
creditCarNumber += 1
creditCarNumber
}
//测试
def main(args: Array[String]): Unit = {
println(CreitCard.generateCCNumver())
println(CreitCard.generateCCNumver())
println(CreitCard.generateCCNumver())
println(CreitCard.generateCCNumver())
println(CreitCard.generateCCNumver())
println(CreitCard.generateCCNumver())
}
}
scala中类的apply方法
遇到如下形式的表达式时,apply方法就会被调用:
Object(参数1,参数2,…,参数N)
通常,在一个类的伴生对象中定义apply方法,在生成这个类的对象时,就省去了new关键字。
class Student4(var stuName:String) {
}
object Student4 {
/**
* 定义Student4的apply方法
*/
def apply(name:String): Student4 = {
println("调用了apply方法")
new Student4(name)
}
def main(args: Array[String]): Unit = {
//使用主构造器创建学生对象
var s1 = new Student4("Tom")
println(s1.stuName)
//通过apply方法创建学生对象
var s2 = Student4("Mary")
println(s2.stuName)
}
}
上面代码的执行结果如下图: