Scala中的类和对象

59 阅读5分钟

(一)面向对象的相关概念

1.什么是面向对象?

它是一种编程思想,它是基于面向对象的,强调的是以对象为基础完成各种操作。

2.面向对象的三大思想特点是什么?

(1) 更符合人们的思考习惯

(2) 把复杂的事情简单化

(3) 把程序员从执行者变成指挥者

3. 面向对象的三大特征是

(1) 封装

(2) 继承

(3) 多态

封装,隐藏实现细节;继承,不劳而获的幸福;多态:丰富多彩的世界。

1. 什么是类class? 类是属性行为的集合。

(1) 属性也叫成员变量:名词,用来描述事物的外在特征

(2) 行为也叫成员方法:动词,表示事物能做什么

(二)创建类和对象

在Scala中,用class来创建类,用new来创建对象。

例如

// 类是属性的集合
// Student,构造函数用来创建对象的
//    辅助构造函数,提供多种创建对象的方式
class Student(var name: String, var age: Int) {
    println("构造函数被调用...")
    
    def sayHi(): Unit = {
        println(s"我是${name}, 我今年${age}")
    }
    
    // 辅助构造函数
    // (1)它的名字就是this
    // (2) 它内部的第一句代码就必须是调用 主构造函数 this("无名氏",0)
    def this() = {
        this("无名氏", 0)
        println("辅助构造函数被调用...")
    }
    
    def this(name: String) = {
        this(name, 0)
        println("辅助构造函数被调用...")
    }
}

object Main {
    def main(args: Array[String]): Unit = {
        // 创建一个学生对象
        // val stu1 = new Student("小花", 18)
        // 调用对象的方法
        // stu1.sayHi()
        // stu1.age = 19
        // 调用对象的方法
        // stu1.sayHi()
        
        // 这里没有设置参数,它会调用辅助构造函数
        // val stu2 = new Student()
        // stu2.sayHi()

        // 这里设置了一个参数,它会调用辅助构造函数
        val stu3 = new Student("小明")
        stu3.sayHi()
    }
}

这种设计模式提供了很好的灵活性,可以根据不同的需求使用不同的构造函数来创建对象。

辅助构造函数的特点:

  1. 方法名必须是 this
  2. 第一行必须调用主构造函数或其他辅助构造函数
  3. 提供多种创建对象的方式
  4. 可以添加额外的初始化逻辑

(三)定义和访问成员变量

定义和访问成员变量。

1. var/val  来定义成员变量

2. 对象可以通过对象名. 成员变量的方式来访问成员变量

说明需求

1.定义一个Person类,包含姓名和年龄字段

2.创建一个名为张三,年龄为20的对象

3.打印对象的名字和年龄

步骤

1. 创建一个Object类,添加main方法

2. 创建Person类,添加姓名字段和年龄字段,并对字段进行初始化,让scala自动推断

3. 在main方法中创建Person类对象,设置成员变量为张三,20

4. 打印对象的名字和年龄

(四)定义和访问成员方法

类可以有自己的行为,scala中也可以通过定义成员方法来定义类的行为。

在scala的类中,使用def定义成员方法。

def 方法名(参数1:数据类型 , 参数2:数据类型): [return type] = {

// 方法体

}

注意:返回值的类型可以不写,由Scala自动进行类型推断。

一个名为customer的类,有两个属性,一个方法。

image.png

(五)理解构造器

构造器是一个函数,在new的时候,被自动调用,它的作用是实例化对象。

new Class() 就是在调用构造器,或者叫调用构造函数。

对应着生活中的例子:类就是模具,对象就是这个模具生产的产品。

image.png

(六)构造函数的参数

有没有方法可以直接在定义对象的时候就去给成员赋值?

在scala中,直接在定义类时,补充参数即可。

// 类是属性的集合
// Student,构造函数用来创建对象的
//    辅助构造函数,提供多种创建对象的方式
class Student(var name: String, var age: Int) {
    println("构造函数被调用...")
    
    def sayHi(): Unit = {
        println(s"我是${name}, 我今年${age}")
    }
    
    // 辅助构造函数
    // (1)它的名字就是this
    // (2) 它内部的第一句代码就必须是调用 主构造函数 this("无名氏",0)
    def this() = {
        this("无名氏", 0)
        println("辅助构造函数被调用...")
    }
    
    def this(name: String) = {
        this(name, 0)
        println("辅助构造函数被调用...")
    }
}

object Main {
    def main(args: Array[String]): Unit = {
        // 创建一个学生对象
        // val stu1 = new Student("小花", 18)
        // 调用对象的方法
        // stu1.sayHi()
        // stu1.age = 19
        // 调用对象的方法
        // stu1.sayHi()
        
        // 这里没有设置参数,它会调用辅助构造函数
        // val stu2 = new Student()
        // stu2.sayHi()

        // 这里设置了一个参数,它会调用辅助构造函数
        val stu3 = new Student("小明")
        stu3.sayHi()
    }
}
// object 对象

// 单例对象,直接使用object来定义。不能用new!
// 单例对象,只有一个,不能通过new来生成多个。它一般用来存放工具方法,常量...。
object Tools {
  val PI = 3.14
  def doubleN(n: Int): Int = {
    n * 2
  }
}

object base48 {
  def main(args: Array[String]): Unit = {
    val rst = Tools.PI * Tools.doubleN(2) // 12.56
    println(s"rst = $rst")  // 修正了字符串插值语法
  }
}

辅助构造函数的特点:

  1. 方法名必须是 this
  2. 第一行必须调用主构造函数或其他辅助构造函数
  3. 提供多种创建对象的方式
  4. 可以添加额外的初始化逻辑

使用私有成员的好处:

  1. 封装性:隐藏内部实现细节
  2. 安全性:防止外部代码意外修改内部状态
  3. 维护性:可以修改内部实现而不影响外部代码
  4. 清晰性:明确区分公共接口和内部实现

这种访问控制机制是面向对象编程的重要特性,有助于构建健壮和可维护的代码。

(七)案例三角形类

例如:

1. 求三角形的面积.

2. 判断是否是一个三角形.

// 定义类

// 主构造函数  
object Base35 {  
  // 封装一个三角形类  
  // 给中学生使用,根据三条边。  
  // 1. 求三角形的面积  
  // 2. 判断是否是一个三角形.  
  class Triangle(var a:Double = 1.0,var b:Double = 1.0,var c:Double = 1.0) {  
    // println(s" ${a} ${c} ${c}")  
    // 检查是否构成三角形,结果是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} ${c} ${c} 不能构成一个三角形")  
        return -1  
      }  
    }  
  }  
  def main(args: Array[String]): Unit = {  
    val t1 = new Triangle(3,4,7) // 6  
    println( t1.getArea() )  
    val t2 = new Triangle(3,4,3) // 6  
    println( t2.getArea() )  
}