Scala是一种函数式的面向对象语言, 它也是支持面向对象编程思想的,也有类和对象的概念。我们依然可以基于Scala语言来开发面向对象的应用程序。
创建类和对象:
Scala中创建类和对象可以通过class和new关键字来实现. 用class来创建类, 用new来创建对象.
代码示例:
创建一个Person类,并创建它的对象, 然后将对象打印到控制台上.
package test4
object Test3 {
class Person {}
def main(args: Array[String]): Unit = {
val person = new Person()
println(person)
}
}
简写方式
如果类是空的,没有任何成员,可以省略{}
如果构造器的参数为空,可以省略()
package test4
object Test3 {
class Person
def main(args: Array[String]): Unit = {
val person = new Person()
println(person)
}
}
定义和访问成员变量
在类中使用var/val
来定义成员变量
对象可以通过对象名.
的方式来访问成员变量
代码示例:
定义一个Person类,包含一个姓名和年龄字段
创建一个名为"张三"、年龄为23岁的对象
打印对象的名字和年龄
class Person {
var name:String = ""
var age:Int = 0
}
def main(args: Array[String]): Unit = {
var person = new Person()
person.name = "张三"
person.age = 23
println(person.name)
println(person.age)
}
使用下划线初始化成员变量
scala中有一个更简洁的初始化成员变量的方式,可以让代码看起来更加简洁, 更优雅.
代码案例:
package test5
object test1 {
class Person {
var name: String = _
var age: Int = _
}
def main(args: Array[String]): Unit = {
var p = new Person
p.name = "zhangsan"
p.age = 18
println(p.name, p.age)
}
}
定义和访问成员方法
类可以有自己的行为,scala中也可以通过定义成员方法来定义类的行为。
格式
def 方法名(参数1:数据类型, 参数2:数据类型): [return type] = {
//方法体
}
代码示例:
package test5
object test2 {
class Customer {
var name: String = _
var age: Int = _
def printHello(msg: String) = {
println(msg)
}
}
def main(args: Array[String]): Unit = {
var customer = new Customer
customer.name = "张三"
customer.age = 20
println(customer.name, customer.age)
customer.printHello("hello")
}
}
访问权限修饰符
代码示例:
package test5
object test3 {
class Customer {
private var name: String = _
private var age: Int = _
def getName() = name
def setName(name: String) = this.name = name
def getAge() = age
def setAge(age: Int) = this.age = age
private def printHello() = {
println("hello")
}
}
def main(args: Array[String]): Unit = {
var customer = new Customer
customer.setName("zhangsan")
customer.setAge(20)
println(customer.getName(), customer.getAge())
// customer.printHello() 外界无法访问这个函数
}
}
类的构造器
当创建对象的时候,会自动调用类的构造器。之前使用的都是默认构造器,接下来我们要学习如何自定义构造器。
主构造器
辅助构造器
主构造器
格式:
class 类名(var/val 参数名:类型 = 默认值, var/val 参数名:类型 = 默认值){
//构造代码块
}
代码示例:
定义一个Person类,通过主构造器参数列表定义姓名和年龄字段,并且设置它们的默认值为张三, 23
在主构造器中输出"调用主构造器"
创建"李四"对象(姓名为李四,年龄为24),打印对象的姓名和年龄
创建"空"对象,不给构造器传入任何的参数,打印对象的姓名和年龄
创建"测试"对象,不传入姓名参数,仅指定年龄为30,打印对象的姓名和年龄
package test5
object test4 {
class Person(var name: String = "zhangsan", var age: Int = 23) {
println("调用主构造器")
}
def main(args: Array[String]): Unit = {
var p1 = new Person()
println(p1.name, p1.age)
var p2 = new Person("lisi", 24)
println(p2.name, p2.age)
var p3 = new Person(age = 30)
println(p3.name, p3.age)
}
}
辅助构造器
定义辅助构造器与定义方法一样,也使用def
关键字来定义
辅助构造器的默认名字都是this
, 且不能修改.
格式:
def this(参数名:类型, 参数名:类型) {
// 第一行需要调用主构造器或者其他构造器
// 构造器代码
}
代码示例:
package test5
object test5 {
class Customer(var name: String, var address: String) {
def this(arr: Array[String]) {
this(arr(0), arr(1))
}
}
def main(args: Array[String]): Unit = {
var customer = new Customer(Array("zhangsan", "beijin"))
println(customer.name, customer.address)
}
}
单例对象
scala中是没有static关键字的,要想定义类似于Java中的static变量、static方法,就要使用到scala中的单例对象了, 也就是object.
定义单例对象
格式:
object 单例对象名{ } //定义一个单例对象.
代码案例:
package test5
object test6 {
object Dog {
val leg_num = 4
def showLeg() = {
println("大黄有四条腿")
}
}
def main(args: Array[String]): Unit = {
println(Dog.leg_num)
Dog.showLeg()
}
}
定义伴生对象
package test5
object test7 {
class Generals {
def toWar = println(s"武将拿着${Generals.armsName}武器, 上阵杀敌!")
}
object Generals {
private var armsName = "青龙偃月刀"
}
def main(args: Array[String]): Unit = {
var generals = new Generals
generals.toWar
}
}
private[this]访问权限
定义一个Person类,包含一个name字段, 该字段用private[this]修饰
定义Person类的伴生对象,定义printPerson方法
测试伴生对象是否能访问private[this]权限的成员
package test5
object test8 {
class Person(private[this] var name: String) {}
object Person {
def printPerson(p: Person) = println(p.name)
}
def main(args: Array[String]): Unit = {
var person = new Person("张三")
Person.printPerson(person)
}
}
注意: 上述代码,会编译报错。但移除掉[this]就可以访问了
apply方法
免new
的动作, 这种写法非常简便,优雅。免new
, 我们就要通过伴生对象的apply方法来实现。格式:
object 伴生对象名 {
def apply(参数名:参数类型, 参数名:参数类型...) = new 类(...)
}
创建对象 :
val 对象名 = 伴生对象名(参数1, 参数2...)
代码示例:
定义一个Person类,它包含两个字段:姓名和年龄
在伴生对象中定义apply方法,实现创建Person对象的免new操作.
在main方法中创建该类的对象,并打印姓名和年龄
package test5
object test9 {
//定义person类
class Person(var name: String = "", var age: Int = 0)
//定义person的伴生对象
object Person {
//定义apply方法,实现创建Person对象的时候免new
def apply(name: String, age: Int) = new Person(name, age)
}
def main(args: Array[String]): Unit = {
val p = Person("张三", 23)
println(p.name, p.age)
}
}
定义工具类
Scala中工具类的概念和Java中是一样的, 都是
object单例对象
满足上述的要求.代码示例:
需求:
编写一个DateUtils工具类专门用来格式化日期时间
定义一个方法,用于将日期(Date)转换为年月日字符串,例如:2030-10-05
定义一个方法, 用于将年月日字符串转换为日期(Date).
步骤:
定义一个DateUtils单例对象
在DateUtils中定义日期格式化方法(date2String)和解析字符串方法(string2Date)
使用SimpleDateFormat来实现String和Date之间的相互转换
代码案例:
package test5
import java.text.SimpleDateFormat
import java.util.Date
object Test10 {
object DateUtils {
var sdf: SimpleDateFormat = null
def date2String(date: Date, template: String): String = {
sdf = new SimpleDateFormat(template)
sdf.format(date)
}
def string2Date(dateString: String, template: String) = {
sdf = new SimpleDateFormat(template)
sdf.parse(dateString)
}
}
def main(args: Array[String]): Unit = {
val s = DateUtils.date2String(new Date(), "yyyy-MM-dd")
println("格式化日期: " + s)
val d = DateUtils.string2Date("2023年5月21日", "yyyy年MM月dd日")
println("解析字符串: " + d)
}
}