一. 面向对象的相关概念
1. 什么是面向对象?
它是一种编程思想,它是基于面向对象的,强调的是以对象为基础完成各种操作。
2. 面向对象的三大思想特点是什么?
(1) 更符合人们的思考习惯
(2) 把复杂的事情简单化
(3) 把程序员从执行者变成指挥者
3. 什么是类class? 类是属性和行为的集合。
(1) 属性也叫成员变量:名词,用来描述事物的外在特征
(2) 行为也叫成员方法:动词,表示事物能做什么
[举例]:学生有姓名和年龄这些是属性,学生要学习,要吃饭这些是行为。
4. 面向对象的三大特征是
(1) 封装
(2) 继承
(3) 多态
[举例]: 封装,隐藏实现细节;继承,不劳而获的幸福;多态:丰富多彩的世界。
二. 创建类和对象
在Scala中,用class来创建类,用new来创建对象。
步骤:
1. 使用IDEA创建一个scala项目,并创建object类。
2. 设置项目名,包名,项目地址。注意不要使用中文,空格,特殊符号作为名字及路径名。
object Base30 {
// Person 就是一个类名,理解为页签名。
// 前方有大写的P!
// 类名一般来说是名词
// 1. 定义类
class Person() {}
class Student() {}
def main(args: Array[String]): Unit = {
// 2. 实例化对象
val p1 = new Person()
val s1 = new Student()
println(p1)
println(s1)
}
}
结果如图:
三. 定义和访问成员变量
定义和访问成员变量。
1. var/val 来定义成员变量
2. 对象可以通过对象名. 成员变量的方式来访问成员变量
说明需求
1. 定义一个Person类,包含姓名和年龄字段
2. 创建一个名为张三,年龄为20的对象
3. 打印对象的名字和年龄
步骤
1. 创建一个Object类,添加main方法
2. 创建Person类,添加姓名字段和年龄字段,并对字段进行初始化,让scala自动推断
3. 在main方法中创建Person类对象,设置成员变量
4. 打印对象的名字和年龄
object Base31 {
class Student() {
// 在类中,定义成员变量
// var val 修饰的变量有什么区别
// val 不可修改
// var 可修改
var name: String = "小花"
var age: Int = 18
}
def main(args: Array[String]): Unit = {
val s1 = new Student()
// 访问成员变量
println(s1.name)
// 给成员变量赋值
s1.name = "小花花"
println(s1.name)
println(s1.age)
}
}
结果如图:
四. 定义和访问成员方法
类可以有自己的行为,scala中也可以通过定义成员方法来定义类的行为。
格式:
在scala的类中,使用def定义成员方法。
注意:返回值的类型可以不写,由Scala自动进行类型推断。
object Base32 {
// 把功能都封装在class中
// 1、属性
// 2、方法
// 3、辅助构造器
class Student() {
// 1、类的属性 - 变量
var name: String = "小花"
var age: Int = 18
// 2、类的方法 - 函数
def say(): Unit = {
println(s"$name, $age")
}
}
def main(args: Array[String]): Unit = {
// 实例化对象
val s1 = new Student()
s1.say()
}
}
结果如图:
object Base33 {
// 把功能都封装在class中
// 1、属性
// 2、方法
// 3、辅助构造器
class Student(var name: String = "小花", var age: Int = 18) {
println("Student....被调用了....")
// 1、类的属性 - 变量
// var name: String = "小花"
// var age: Int = 18
// 2、类的方法 - 函数
def say(): Unit = {
println(s"$name, $age")
}
}
def main(args: Array[String]): Unit = {
// 实例化对象
val s1 = new Student()
s1.say()
val s2 = new Student("小明", 19)
s2.say()
}
}
结果如图:
案例
封装一个三角形类 给中学生使用,根据三条边。
1、判断是否是一个三角形。
2、求三角形的面积
class Triangle(var a: Double = 1.0, var b: Double = 1.0, var c: Double = 1.0) {
println(s"$a $b $c")
// 检查是否构成三角形,结果是boolean
def check(): Boolean = {
// 构成三角形的条件是:任意两边之和 > 第三边
return a + b > c && b + c > a && a + c > b
}
}
def main(args: Array[String]): Unit = {
print("请输入第一条边")
val a = scala.io.StdIn.readDouble()
print("请输入第二条边")
val b = scala.io.StdIn.readDouble()
print("请输入第三条边")
val c = scala.io.StdIn.readDouble()
val t1 = new Triangle(a, b, c)
if (t1.check()) {
println("能构成三角形")
} else {
println("不能构成三角形")
}
}
结果如图:
class Triangle(var a: Double = 1.0, var b: Double = 1.0, var c: Double = 1.0) {
// 检查是否构成三角形,结果是boolean
def check(): Boolean = {
// 构成三角形的条件是:任意两边之和 > 第三边
return a + b > c && b + c > a && a + c > b
}
// 计算面积:根据三角形的三边计算面积?
def getArea(): Double = {
if (check()) {
var s = (a + b + c) / 2
s = Math.sqrt(s * (s - a) * (s - b) * (s - c))
return s
} else {
println(s"$a $b $c: 不能构成一个三角形")
return -1
}
}
}
def main(args: Array[String]): Unit = {
val t1 = new Triangle(3,4,5)
println(t1.getArea())
val t2 = new Triangle(3,4,3)
println(t2.getArea())
}
结果如图:
五. 成员访问的本质
在本质上和java的set,get类似。 要注意:
1.val定义的变量可以生成 get。可以访问。
2.var定义的变量可以生成 get + set。可以访问 + 修改。
3.使用private修饰的变量,既不可以访问,也不可以修改。
六. 主构造函数
[提问]:有没有方法可以直接在定义对象的时候就去给成员赋值?在java中,使用public定义与类同名的方法。
在scala中,直接在定义类时,补充参数即可。
格式: class 类名([参数列表])
Class 类名(参数列表),参数列表中的变量可以用var|val,也可以不用。
用val或var定义,在类外可以访问
不用val|var定义,在类外不可以访问 内部只读,不可改写
案例一
// 构造器的默认值
// 必填写:姓名,年龄,
// 有默认值的项
// 性别:男
// 民族:汉
class Student(var name: String, var age: Int, var gender: String = "男", var nav: String = "汉族") {
def say(): Unit = {
println(s"${name}, ${age}, ${gender}, ${nav}")
}
}
def main(args: Array[String]): Unit = {
// var s0 = new Student() // gender 和 nav 使用默认值
var s1 = new Student("小明", 19) // gender 和 nav 使用默认值
s1.say()
var s2 = new Student("小花", 18, "女", "回族")
s2.say()
}
结果如图:
案例二
// 构造器中的参数的类型
// 1. val定义的属性,不能修改
// 2. var定义的属性,可以修改
// 3. 没有val,也没有var的,不是对象的属性。不能使用.语法来访问。
class Student(val name: String, var age: Int, gender: String = "男") {
def say(): Unit = {
println(s"${name}, ${age}, ${gender}")
}
}
def main(args: Array[String]): Unit = {
var s1 = new Student("小明", 19) // gender 使用默认值
s1.age = 20
s1.say()
}
结果如图:
七. 辅助构造函数
[提问]:构造函数只能有一个吗?
答,可以有很多个。
辅助构造器的作用
1. 提供多种初始化方式:
辅助构造器允许您为类提供多种初始化选项,使得创建对象时更加灵活。例如,您可以定义一个不需要所有参数的构造器。
2.简化对象创建:
通过定义多个辅助构造器,您可以简化对象的创建过程,避免在主构造器中处理过多的参数。
3.调用主构造器:
辅助构造器可以通过 this 关键字调用主构造器,从而确保所有初始化逻辑都集中在主构造器中。
// 多种注册用户的方式 --- 辅助构造器
// 1. 手机号 + 密码
// 2. 邮箱 + 密码 + 用户名
// 姓名
class Register(val name: String, var email: String, var pwd: String, var phone: String) {
println("主构造器被调用")
// 辅助构造器
// 1. 名称一定是this
// 2. 在辅助构造器内部,一定要调用主构造器this
// 3. 可以有多个
def this(phone: String, pwd: String) {
this("随机用户xxxx", "xxx@qq.com", pwd, phone) // 调用主构造器
println("辅助构造器被调用")
}
def this(email: String, pwd: String, name: String) {
this(name, email, pwd, "13600000000") // 调用主构造器
println("辅助构造器被调用")
}
def say(): Unit = {
println(s"姓名: ${name}, 邮箱: ${email}, 密码: ${pwd}, 手机号: ${phone}")
}
}
def main(args: Array[String]): Unit = {
// val r1 = new Register("小明", "123123@qq.com", "123456", "13617885566")
// 调用辅助构造器
val r1 = new Register("13617885566", "123456")
val r2 = new Register("9456651@qq.com", "123456", "小明")
r1.say()
r2.say()
}
结果如图: