一、类
(一)类的定义
对象是类的具体实例,类是抽象的,不占用内存,而对象是具体的,占用存储空间。
class User {
private var name = "张三丰"
private var gender = "男"
private var age = 25
def speak(): Unit = println(name + ", " + gender + ", 今年" + age + "岁了~")
}
(二)类的实例化
二、单例对象
(一)单例对象概念
Scala中没有静态方法或静态字段,但是可以使用关键字object定义一个单例对象,单例对象中的方法相当于Java中的静态方法,可以直接使用“单例对象名.方法名”方式进行调用。单例对象除了没有构造器参数外,可以拥有类的所有特性。
(二)案例演示
object Person {
private var name = "陈燕文"
private var gender = "女"
private var age = 18
def speak(): Unit = println(name + ", " + gender + ", 今年" + age + "岁了~")
}
三、伴生对象
(一)伴生对象概念
当单例对象的名称与某个类的名称一样时,该对象被称为这个类的伴生对象。类被称为该对象的伴生类。类和它的伴生对象必须定义在同一个文件中,且两者可以互相访问其私有成员。
(二)案例演示
四、get和set方法
(一)生成原则
Scala默认会根据类的属性的修饰符生成不同的get和set方法
1、val修饰的属性
系统会自动生成一个私有常量属性和一个公有get方法。
2、var修饰的属性
系统会自动生成一个私有变量属性和一对公有get/set方法。
3、private var修饰的属性
系统会自动生成一对私有get/set方法,相当于类的私有属性,只能在类的内部和伴生对象中使用。
4、private[this]修饰的属性
系统不会生成get/set方法,即只能在类的内部使用该属性。
(二)案例演示
任务1、利用系统自动生成的get和set方法
(1)创建Dog类
package net.py.obj
class Dog {
val id: Int = 1 // 系统会自动生成公共的get方法
var name: String = "瑞瑞" // 系统会自动生成公共的get和set方法
private var gender: String = "公" // 系统会自动生成私有的get和set方法,只有伴生对象可以访问
private[this] var age: Int = 5 // 系统不会生成get和set方法,即使伴生对象也无法访问
}
(2)编译成字节码文件
将Dog.scala编译成Dog.class,在项目的out目录里,逐层点开,找到Dog,那就是生成字节码文件
(3)将字节码文件反编译为Java代码
(4)说明反编译生成的Java代码
使用name属性举例,在Scala中,get和set方法并非被命名为getName和setName,而是被命名为name和name_=,由于JVM不允许在方法名中出现=,因此=被翻译成KaTeX parse error: Expected group after '_' at position 97: …法对应的name()和name_̲eq()方法,且都为public;属性gender由于使用private var修饰,因此生成了private修饰的get和set方法 - gender()和gender_$eq();属性age由于使用private[this]修饰,因此没有生成get和set方法,只能在类的内部使用。
(5)创建单例对象用来测试Dog类
任务2、用户自己编写私有属性的Scala风格的get和set方法
创建Cat类
任务3、用户自己编写私有属性的Java风格的get和set方法
创建Bird类
五、构造器
(一)主构造器
1、构造器参数带val或var
在net.py.consrtucuor包里创建Person类
2、构造器参数带访问权限
可以通过对主构造器的参数添加访问修饰符来控制参数的访问权限
创建Person类,将参数age设置为私有的,参数name设置为不可修改(val)
class Person (val name: String, private var age: Int) {
}
3、构造器参数不带var或val
class Person (name: String, age: Int) {
}
可以改写成带访问权限的参数
class Person (private[this] val name: String, private[this] val age: Int) {
}
4、类的初始化语句
在net.py.constructor包里创建Dog类
package net.py.constructor
class Dog (var name: String, var age: Int){
name = "瑞瑞"
age = 5
println("主构造器被调用了~")
def speak(): Unit = println(name + "今年" + age + "岁了~")
}
// 伴生对象
object Dog {
def main(args: Array[String]): Unit = {
val dog = new Dog("", 0)
dog.speak()
}
}
运行程序,查看结果
主构造器被调用了~
瑞瑞今年5岁了~
5、私有化构造器
package net.py.constructor
class Cat private (var name: String, var age: Int) {
def speak(): Unit = {
println(name + "今年" + age + "岁了~")
}
}
// 伴生对象
object Cat {
def main(args: Array[String]): Unit = {
val cat = new Cat("刘璐", 9)
cat.speak()
}
}
运行程序,查看结果
刘璐今年9岁了~
6、无参构造器
在net.py.constructor包里创建Bird类
package net.py.constructor
class Bird () { // 显式定义无参构造器
var name = "mike"
var age = 7
def speak(): Unit = {
println(name + "今年" + age + "岁了~")
}
}
// 伴生对象
object Bird {
def main(args: Array[String]): Unit = {
val bird = new Bird() // 调用无参构造器实例化
bird.speak()
}
}
运行程序,查看结果
mike今年7岁了~
(二)辅助构造器
1、定义辅助构造器的注意事项
辅助构造器的方法名称为this
每一个辅助构造器的方法体中必须首先调用其他已定义的构造器
辅助构造器的参数不能使用var或val进行修饰
2、案例演示
(1)无参主构造器与有参辅助构造器
package net.py.constructor
class Student {
private var name = "淑英"
private var age = 18
// 定义单参辅助构造器
def this(name: String) = {
this() // 调用无参主构造器
this.name = name
}
// 定义双参辅助构造器
def this(name:String, age: Int) = {
this(name) // 调用单参辅助构造器
this.age = age
}
// 重写toString方法
override def toString: String = name + "今年" + age + "岁了~"
}
// 伴生对象
object Student {
def main(args: Array[String]): Unit = {
// 调用无参构造器实例化
val student1 = new Student()
println(student1)
// 调用单参辅助构造器实例化
val student2 = new Student("禹欢")
println(student2)
// 调用双参辅助构造器实例化
val student3 = new Student("黎塘", 19)
println(student3)
}
}
运行程序,查看结果
淑英今年18岁了~
禹欢今年18岁了~
黎塘今年19岁了~
(2)有参主构造器与有参辅助构造器
package net.py.constructor
class Teacher (private var name: String, private var age: Int) {
private var gender = ""
def this(name: String, age: Int, gender: String) = {
this(name, age) // 调用双参主构造器
this.gender = gender
}
// 重写toString方法
override def toString: String = name + "," + gender + ",今年" + age + "岁了~"
}
// 伴生对象
object Teacher {
def main(args: Array[String]): Unit = {
// 调用三参辅助构造器实例化
val teacher = new Teacher("萧红", 20, "女")
println(teacher)
}
}
运行程序,查看结果
萧红,女,今年20岁~
六、抽象类
(一)抽象类的定义
abstract class 类名 {
}
(二)抽象类的特征
1抽象类不能被实例化。
2抽象类中可以定义抽象字段(没有初始化的字段)和抽象方法(没有被实现的方法),也可以定义被初始化的字段和被实现的方法。
(三)案例演示
1、创建抽象类 - Person
在net.py.absclass包里创建Person抽象类
package net.py.absclass
abstract class Person {
var name: String // 抽象字段
var age: Int // 抽象字段
var address: String = "泸州市纳溪区" // 普通字段
// 抽象方法
def speak()
// 普通方法
def walk(): Unit = {
print(name + "弹钢琴~")
}
}
2、继承抽象类,创建普通类 - Teacher
在net.py.absclass包里创建Teacher普通类
`package net.py.absclass
class Teacher extends Person {
// 实现抽象字段(可以不加override)
var name: String = “萧红”
var age: Int = 20
// 实现抽象方法,不用加override
def speak(): Unit = {
println(name + “,今年” + age + “岁,家住” + address + “,擅长唱歌舞蹈。” )
}
// 重写普通方法,必须加override
override def walk(): Unit = {
println(name + “喜欢弹钢琴~”)
}
}
`
3、创建测试单例对象 - TestTeacher
在net.py.absclass包里创建TestTeacher单例对象
4、运行程序,查看结果
萧红,今年20岁,家住泸州市纳溪区,擅长唱歌舞蹈。
萧红喜欢弹钢琴~
七、特质
(一)特质的概念
(二)特质的定义
1、语法格式
2、案例演示
任务1、创建宠物特质 - Pet
package net.py.mytrait
trait Pet {
// 抽象字段
var name: String
var age: Int
// 抽象方法
def speak
// 普通方法
def eat: Unit = {
print(name + "在吃东西~")
}
}
任务2、创建奔跑特质 - Runnable
任务3、创建飞翔特质 - Flyable
(三)特质的实现
1、语法格式
(1)实现一个特质
class 类名 extends 特质名 {
// 实现抽象字段
// 实现抽象方法
}
(2)实现多个特质
class 类名 extends 特质名1 with 特质名2 with 特质名3 …… with 特质名n {
// 实现抽象字段
// 实现抽象方法
}
2、案例演示
任务1、实现一个特质
package net.py.mytrait
class Cat extends Pet {
// 实现抽象字段
var name: String = "虎丸"
var age: Int = 3
// 实现抽象方法
def speak: Unit = {
println(name + "今年" + age + "岁了~")
}
// 重写普通方法
override def eat: Unit = {
println(name + "在吃鱼虾~")
}
}
// 伴生对象
object Cat {
def main(args: Array[String]): Unit = {
// 创建猫对象
val cat = new Cat()
// 调用对象方法
cat.speak
cat.eat
}
}
任务2、实现多个特质
package net.py.mytrait
class Bird extends Pet with Runnable with Flyable {
var name: String = "玲玲"
var age: Int = 2
def speak: Unit = {
println("鸟儿[" + name + "]今年" + age + "岁了~")
}
def run: Unit = {
println("鸟儿[" + name + "]在欢快地奔跑~")
}
def fly: Unit = {
println("鸟儿[" + name + "]在自由地飞翔~")
}
}
// 伴生对象
object Bird {
def main(args: Array[String]): Unit = {
// 创建鸟对象
val bird = new Bird()
// 调用对象方法
bird.speak
bird.run
bird.fly
}
}
运行程序,查看结果
鸟儿[玲儿]今年2岁了~
鸟儿[玲儿]在欢快的奔跑~
鸟儿[玲儿]在自由的飞翔~