类和对象
scala是支持面向对象的,也有类和对象的概念。我们依然可以基于scala语言来开发面向对象的应用程序。
创建类和对象
用法
- 使用
class
来定义一个类 - 使用
new
来创建对象
示例
创建一个Person类,并创建它的对象
步骤
- 创建一个scala项目,并创建一个Object
- 添加main方法
- 创建类和对象
实现
- 在IDEA中创建项目,并创建一个Object(main方法必须放在Object中)
- 添加main方法
- 创建一个Person类
- 在main方法中创建Person类对象
参考代码
object _01ClassDemo {
// 创建类
class Person{}
def main(args: Array[String]): Unit = {
// 创建对象
val p = new Person()
println(p)
}
}
简写方式
用法
- 如果类是空的,没有任何成员,可以省略
{}
- 如果构造器的参数为空,可以省略
()
示例
使用简写方法重新创建Person类和对象
参考代码
object _02ClassDemo {
// 创建类,省略花括号
class Person
def main(args: Array[String]): Unit = {
// 创建对象,省略括号
val person = new Person
}
}
# 定义和访问成员变量
一个类会有自己的属性,例如:人这样一个类,有自己的姓名和年龄。我们接下来学习在类中定义、和访问成员变量。
用法
- 在类中使用
var/val
来定义成员变量 - 对象直接使用成员变量名称来访问成员变量
示例
- 定义一个Person类,包含一个姓名和年龄字段
- 创建一个名为"张三"、年龄为20岁的对象
- 打印对象的名字和年龄
步骤
- 创建一个Object,添加main方法
- 创建Person类,添加姓名字段和年龄字段,并对字段进行初始化,让scala自动进行类型推断
- 在main方法中创建Person类对象,设置成员变量为"张三"、20
- 打印对象的名字和年龄
参考代码
object _03ClassDemo {
class Person {
// 定义成员变量
var name = ""
var age = 0
}
def main(args: Array[String]): Unit = {
// 创建Person对象
val person = new Person
person.name = "zhangsan"
person.age = 20
// 获取变量值
println(person.name)
println(person.age)
}
}
# 使用下划线初始化成员变量
scala中有一个更简洁的初始化成员变量的方式,可以让代码看起来更加简洁。
用法
- 在定义
var
类型的成员变量时,可以使用_
来初始化成员变量- String => null
- Int => 0
- Boolean => false
- Double => 0.0
- …
val
类型的成员变量,必须要自己手动初始化
示例
- 定义一个Person类,包含一个姓名和年龄字段
- 创建一个名为"张三"、年龄为20岁的对象
- 打印对象的名字和年龄
步骤
- 创建一个Object,添加main方法
- 创建Person类,添加姓名字段和年龄字段,指定数据类型,使用下划线初始化
- 在main方法中创建Person类对象,设置成员变量为"张三"、20
- 打印对象的名字和年龄
参考代码
object _04ClassDemo {
class Person{
// 使用下划线进行初始化
var name:String = _
var age:Int = _
}
def main(args: Array[String]): Unit = {
val person = new Person
println(person.name)
println(person.age)
}
}
# 定义成员方法
类可以有自己的行为,scala中也可以通过定义成员方法来定义类的行为。
定义
在scala的类中,也是使用def
来定义成员方法
示例
-
创建一个Customer类
[外链图片转存失败(img-Bi4nl1u5-1569034092139)(assets/1557322180244.png)]
-
创建一个该类的对象,并调用printHello方法
步骤
- 创建一个Object,添加main方法
- 创建Customer类,添加成员变量、成员方法
- 在main方法中创建Customer类对象,设置成员变量值(张三、男)
- 调用成员方法
参考代码
object _05ClassDemo {
class Customer {
var name:String = _
var sex:String = _
// 定义成员方法
def sayHi(msg:String) = {
println(msg)
}
}
def main(args: Array[String]): Unit = {
val customer = new Customer
customer.name = "张三"
customer.sex = "男"
customer.sayHi("你好")
}
}
# 访问修饰符
和Java一样,scala也可以通过访问修饰符,来控制成员变量和成员方法是否可以被访问。
定义
Java中的访问控制,同样适用于scala,可以在成员前面添加private/protected关键字来控制成员的可见性。但在scala中,没有public关键字
,任何没有被标为private或protected的成员都是公共的
案例
- 定义一个Person类
- 在main方法中创建该类的对象,测试是否能够访问到私有成员
参考代码
object _02AccessDemo {
class Person {
// 定义私有成员变量
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 getNameAndAge = {
name -> age
}
}
def main(args: Array[String]): Unit = {
val person = new Person
person.setName("张三")
person.setAge(10)
println(person.getName())
println(person.getAge())
}
}
类的构造器
当创建类对象的时候,会自动调用类的构造器。之前使用的都是默认构造器,我们接下来要学习如何自定义构造器。
主构造器
我们学习过,Java的构造器,有构造列表和构造代码块
class Person {
// 成员变量
private String name;
private Integer age;
// Java构造器
public Person(String name, Integer age) {
// 初始化成员变量
this.name = name;
this.age = age;
}
}
在scala中,我们可以使用更简洁的语法来实现。
语法
class 类名(var/val 参数名:类型 = 默认值, var/val 参数名:类型 = 默认值){
// 构造代码块
}
[!NOTE]
- 主构造器的参数列表是直接定义在类名后面,添加了val/var表示直接通过主构造器定义成员变量
- 构造器参数列表可以指定默认值
- 创建实例,调用构造器可以指定字段进行初始化
- 整个class中除了字段定义和方法定义的代码都是构造代码
示例
- 定义一个Person类,通过主构造器参数列表定义姓名和年龄字段,并且设置它们的默认值
- 在主构造器中输出"调用主构造器"
- 创建"张三"对象(姓名为张三,年龄为20),打印对象的姓名和年龄
- 创建"空"对象,不给构造器传入任何的参数,打印对象的姓名和年龄
- 创建"man40"对象,不传入姓名参数,指定年龄为40,打印对象的姓名和年龄
参考代码
object _06ConstructorDemo {
// 定义类的主构造器
// 指定默认值
class Person(var name:String = "", var age:Int = 0) {
println("调用主构造器")
}
def main(args: Array[String]): Unit = {
// 给构造器传入参数
val zhangsan = new Person("张三", 20)
println(zhangsan.name)
println(zhangsan.age)
println("---")
// 不传入任何参数
val empty = new Person
println(empty.name)
println(empty.age)
println("---")
// 指定字段进行初始化
val man40 = new Person(age = 40)
println(man40.name)
println(man40.age)
}
}
辅助构造器
在scala中,除了定义主构造器外,还可以根据需要来定义辅助构造器。例如:允许通过多种方式,来创建对象,这时候就可以定义其他更多的构造器。我们把除了主构造器之外的构造器称为辅助构造器。
语法
- 定义辅助构造器与定义方法一样,也使用
def
关键字来定义 - 这个方法的名字为
this
def this(参数名:类型, 参数名:类型) {
// 第一行需要调用主构造器或者其他构造器
// 构造器代码
}
[!DANGER]
辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器
示例
示例说明
- 定义一个Customer类,包含一个姓名和地址字段
- 定义Customer类的主构造器(初始化姓名和地址)
- 定义Customer类的辅助构造器,该辅助构造器接收一个数组参数,使用数组参数来初始化成员变量
- 使用Person类的辅助构造器来创建一个"zhangsan"对象
- 姓名为张三
- 地址为北京
- 打印对象的姓名、地址
参考代码
object _07ConstructorDemo {
class Customer(var name:String = "", var address:String = "") {
// 定义辅助构造器
def this(arr:Array[String]) = {
// 辅助构造器必须要调用主构造器或者其他辅助构造器
this(arr(0), arr(1))
}
}
def main(args: Array[String]): Unit = {
val zhangsan = new Customer(Array("张三", "北京"))
println(zhangsan.name)
println(zhangsan.address)
}
}