问题理解
有个老太太,养了两只白色的猫,它们的名字叫“大花”和“小花”,今年都只有3岁。现在要求编写一个程序,分别描述这两只猫的特征,包括名字、年龄和颜色
问题产生:使用普通的变量描述两只猫,管理起来很麻烦,而且如果老太太又多养了一只猫,难道又要增加变量去描述?
需求分析:猫都有三个属性特征,只是类型可能不一样,可不可以封装一个猫的模板,作为一种新的数据类型?
- 需求1:管理猫的三个特征【属性】
- 需求2:能对猫的三个特征进行操作,而且需要描述猫吃鱼、抓老鼠等行为【方法】
案例研究
```scala object CatDemo { def main(args: Array[String]): Unit = { val cat = new Cat cat.name = “小花” cat.age = 3 cat.color = “白色” printf(“小猫信息如下:%s%d岁名字叫%s\n”, cat.color, cat.age, cat.name) cat.eat() } }
/**
定义一个 Cat 类 */ class Cat { // 省略了 name 属性的类型声明 var name = “” // 默认值必须指定属性的类型 var age: Int = var color: String =
def eat(): Unit = println(“抓老鼠”) } ``` 📝 说明
- 定义一个类的属性时必须指定初始值
- 如果初始值的类型是确定的,那么可以省略属性类型
- 如果初始值是用“_”表示的一个默认值,那么必须指定属性类型,否则报错
✍ 思考
- 上述代码的底层逻辑是什么样的?【具体使用反编译工具查看】Cat.java
- 通过查看 Cat.class 反编译后的代码,发现一个类的属性是私有的,无法直接访问
上述代码中,既然底层属性是私有的,为什么在还能访问呢?
// 创建对象 var | val 对象名[: 类型] = new 类名() ```
类
- 一个 Scala 源文件可以包含多个类
类不能声明为 public(否则报错),因为所有类在底层已经默认是 public 的
属性
属性是类的一个组成部分,也称为成员变量,有以下注意点:
定义的类型可以是任意类型的,包括值类型、引用类型
- 声明一个属性时,必须显式地初始化
- 如果初始化的数据类型可以自动推断,属性的类型声明可以省略
- 如果初始化为 null,一定要加上类型,否则默认该属性的类型是 Null 类型
- 如果初始值使用下划线“”,系统会分配默认值,这时必须明确属性类型 | 类型 | **“”对应的默认值 | | :—-: | :—-: | | Byte/Short/Int/Long | 0 | | Float/Double | 0.0 | | String 和 引用类型 | null | | Boolean** | false |
方法
方法也是类的一个组成部分,也称为成员方法,其实就是函数,具体参考第 4 章
调用机制:和 Java 一样
对象
根据一个类可以创建该类的多个实例(即对象),不同对象的属性是独立的,互不影响,一个对象属性的更改不影响另外一个
创建对象:使用 new 关键字创建一个类的对象,如“val cat: Cat = new Cat”
变量声明:可以使用 var 或 val 关键字声明一个对象变量【Scala 设计者推荐使用 val】
内存分布机制:和 Java 一致
📝 注意点
- 声明对象变量时,Scala 可以根据创建对象的类型自动推断,故类型声明可以省略
- 当声明的和 new 的类型有继承关系即多态时,必须声明类型
✍ 为什么推荐使用 val 关键字声明一个对象变量?