重学scala:scala面向对象编程之类与对象

举报
橙子园 发表于 2022/05/26 00:56:38 2022/05/26
【摘要】 文章目录 一、类1、类的定义2、类的构造器 二、对象1、scala中的object2、scala中的伴生对象3、scala中object的apply方法4、scala中object的ma...

一、类

1、类的定义

scala是支持面向对象的,也有类和对象的概念。

示例:定义一个User类,并添加成员变量/成员方法,创建一个Main object,添加一个main方法,并创建Customer类的对象,并给对象赋值,打印对象中的成员,调用成员方法

class User {
  var name:String = _
  var sex:String = _
  val registerDate:Date = new Date

  def sayHello(msg:String) = {
    println(msg)
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val user = new User
    //给对象的成员变量赋值
    user.name = "张三"
    user.sex = "男"

    println(s"姓名: ${user.name}, 性别:${user.sex}, 注册时间: ${user.registerDate}")
    //对象调用方法  
    user.sayHi("你好!")
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • var name:String = _ 表示使用默认值进行初始化
    例如:String类型默认值是null,Int类型默认值是0,Boolean类型默认值是false

  • val变量不能使用 _ 来进行初始化,因为val是不可变的,所以必须手动指定一个默认值

  • main方法必须要放在一个scala的object(单例对象)中才能执行

2、类的构造器
  • 主构造器
    主构造器是指在类名后面的()里跟上一系列参数
class 类名(var/val 参数名:类型[ = 默认值], var/val 参数名:类型[ = 默认值]){
    // 构造代码块
}

  
 
  • 1
  • 2
  • 3
  • 辅助构造器
    在类中使用this来定义
def this(参数名:类型, 参数名:类型) {
    // 第一行代码必须是调用主构造器、其他辅助构造器、super父类的构造器
    ...
}

  
 
  • 1
  • 2
  • 3
  • 4

例子:

class User(val name:String, var age:Int) {

  val address:String = "hangzhou"

  //定义一个参数的辅助构造器

  def this(name:String) {
    this(name, 35)
  }

  def this(age:Int) {
    this("张三", age)
  }

}

object Main {
  def main(args: Array[String]): Unit = {
    val user1 = new User("李四")
    val user2 = new User("王五", 20)

    println(s"姓名: ${user1.name}, 年龄:${user1.age}")
    println(s"姓名: ${user2.name}, 年龄:${user2.age}")
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

二、对象

1、scala中的object

scala中是没有Java中的静态成员的。如果需要用到static变量、static方法,就要用到scala中的单例对象object,定义单例对象和定义类很像,就是把class换成object。
示例:定义一个工具类,用来格式化日期时间

import java.text.SimpleDateFormat
import java.util.Date

object DateUtils {

  // 在object中定义的成员变量,相当于Java中定义一个静态变量
  // 定义一个SimpleDateFormat日期时间格式化对象
  val simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

  // 相当于Java中定义一个静态方法
  def format(date:Date) = simpleDateFormat.format(date)

  // main是一个静态方法,所以必须要写在object中
  def main(args: Array[String]): Unit = {
    println(DateUtils.format(new Date()))
  }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 工具类或者存放常量可以使用 object 定义一个单例对象
  • 在单例对象中定义的变量,类似于Java中的static成员变量。访问单例对象的成员变量也是使用单例对象名.变量名
  • 在单例对象中定义的方法,类似于Java中的static方法;调用单例对象的方法,直接使用单例对象名.方法名
  • object单例对象的构造代码可以直接写在花括号中
  • 单例对象只能有一个无参的主构造器,不能添加其他参数,即没有(参数)
2、scala中的伴生对象

在同一个scala文件,有一个class和object具有同样的名字,那么就称这个object是class的伴生对象,class是object的伴生类;伴生类和伴生对象的最大特点是,可以相互访问。
示例:

class Person {
  private var name = "李四"

  def printName(): Unit ={
    //在Person类中可以访问伴生对象Person的私有属性
    println(Person.CONSTANT + name)
  }
}

object Person {
  //伴生对象的私有属性
  private val CONSTANT = "hello!"

  def main(args: Array[String]): Unit = {
    val p = new Person

    //使用创建的对象访问私有字段
    p.name = "张三"

    p.printName()
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 伴生类和伴生对象的名字必须是一样的
  • 伴生类和伴生对象需要在一个scala源文件中
  • 伴生类和伴生对象可以互相访问private的属性
3、scala中object的apply方法

先来看一个之前经常使用的例子,使用如下方式来创建一个Array对象。

val a = Array(1, 2, 3, 4)

  
 
  • 1

其实它是这样实现的

class Array -> object Array{  def apply = Array对象}

  
 
  • 1

这种写法非常简便,不需要写一个new,然后一个空格,写类名。直接使用类名来创建对象,由上面可以看出来它是使用在伴生对象中使用apply方法来实现的。我们再来具体的看一下Array伴生对象的apply方法的scala源代码:

在这里插入图片描述

伴生对象的apply方法用来快速地创建一个伴生类的对象。

下面我们写一个例子:

class Customer(var name:String, var age:Int) {

  def getString: String = {
    s"Customer($name, $age)"
  }
}

object Customer {

  // 实现apply方法
  // 返回的是伴生类的对象
  def apply(name:String, age:Int): Customer = new Customer(name, age)

  // 同时apply方法也支持重载
  def apply(name:String):Customer = new Customer(name, 20)

  def apply(age:Int):Customer = new Customer("张三", age)

  def apply():Customer = new Customer("王五", 20)

}

object Exec {
  def main(args: Array[String]): Unit = {
    val p1 = new Customer("赵六", 20)
    val p2 = Customer("李四")
    val p3 = Customer(35)
    val p4 = Customer()

    println(p1.getString)
    println(p2.getString)
    println(p3.getString)
    println(p4.getString)
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述

  • 当遇到类名(参数1, 参数2…)会自动调用apply方法,在apply方法中来创建对象

  • 定义apply时,如果参数列表是空,也不能省略括号(),否则引用的是伴生对象

4、scala中object的main方法

scala和Java一样,如果要运行一个程序,必须有一个main方法。而在Java中main方法是静态的,而在scala中没有静态方法。scala中这个main方法必须放在一个object中

object Exec{
  def main(args:Array[String]) = {
    println("hello!")
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

也可以继承自App Trait(App 特质),然后将需要编写在main方法中的代码写在object的构造方法体内。其本质是调用了App Trait这个特质中的main方法。

示例:

object Exec extends App {
  println("hello!")
}

  
 
  • 1
  • 2
  • 3

文章来源: blog.csdn.net,作者:橙子园,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Chenftli/article/details/124715793

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。