千家信息网

Scala笔记整理(三):Scala面向对象—类详解1

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,[TOC]getter和setter简单类和无参方法需要说明的是,官方给出的参考资料对于这方面讲解得十分详细,目前入门来说,不需要达到这样的理解,只需要可以进行开发即可,这一部分我给出的是官方的一些文
千家信息网最后更新 2026年11月03日Scala笔记整理(三):Scala面向对象—类详解1

[TOC]


getter和setter

简单类和无参方法

需要说明的是,官方给出的参考资料对于这方面讲解得十分详细,目前入门来说,不需要达到这样的理解,只需要可以进行开发即可,这一部分我给出的是官方的一些文档说明,但是后面的定制和注解,就直接简单说明能用就好了。

class PersonOps {    private var age = 0 //你必须初始化一个字段    def increment() {age += 1} //方法默认是公有的    def currentAge() = age}

1)在Scala中,类并不声明为public。Scala源文件可以包含多个类,所有这些类都具有公有可见性。

2)如何进行调用?

object MainOps{    def main(args: Array[String]) {        val personOps = new PersonOps        personOps.increment()        println("currentAge=> " + personOps.currentAge())    }}

3)不能用类直接调用age,因为age是私有字段,只能在PersonOps中访问到。

4)无参方法

println("currentAge=>" + personOps.currentAge())println("currentAge=>" + personOps.currentAge)

建议:对设置值的时候,即改变对象状态值或者状态时使用(),而对于取值来说(不会改变对象的状态和值)去掉()是个不错的风格,这也是我们事例中的方法。

personOps.increment()println("currentAge=> " + personOps.currentAge)

5)你可以通过以不带()的方式声明currentAge来强制这种风格:

class PersonOps {    private var age = 0 //你必须初始化一个字段    def increment() {age += 1} //方法默认是公有的    def currentAge = age}

结果:这样一来在调用时,必须要用不带()的进行方法调用

println("currentAge=>" + personOps.currentAge)

6)带getter和setter的属性

Java中属性定义

public class PersonAge{ //这是Java    private int age;    public int getAge() { return age; }    public void setAge(int age) { this.age=age; }}

getter和setter方式比共有字段(public)好在什么地方呢?

之所以说getter和setter方法比公有字段更好,是因为它们让你可以从简单的get/set机制出发,并在需要的时候做改进。

5)scala中的getter和setter方法

class PersonA{    var age = 0}

a.Scala生成面向JVM的类,其中有一个私有的age字段以及相应的getter方法和setter方法。这两个方法是公有的,因为我们没有将age声明为private。而对私有字段而言,getter和setter方法也是私有的。

a.在Scala中,getter和setter分别叫做age和age_=例如:

val personA = new PersonAprintln("startAge=> " + personA.age)personA.age = 21println("endAge=> " + personA.age)

执行下面的命令:

Scalac PersonOps.scala\src\main\scala\tw\tw>javap -p PersonA.classCompiled from "PersonOps.scala"

然后会生成下面的内容:

public class tw.PersonA {    private int age;    public int age();    public void age_$eq(int);    public tw.PersonA();}

正如你看到的那样,编译器创建了age和age_$eq,是因为JVM不允许在方法名中出现=

说明:在Scala中,getter和setter方法并非被命名为getXxx和setXxx,不过它们的用意是相同的。后面会介绍如何生成Java风格的getXxx和setXxx方法,以使得你的Scala类可以与Java工具实现互操作

定制的getter/setter方法

这部分先不用搞太复杂,直接使用Java版本的getter/setter方法即可,如下面一个类:

class Student {  private var age:Int = 0  def setAge(age:Int): Unit = {    this.age = age  }  def getAge() = age}

测试如下:

scala> val s = new Student()s: Student = Student@1608bb5dscala> sres200: Student = Student@1608bb5dscala> s.getAge()res201: Int = 0scala> s.getAgeres202: Int = 0scala> s.setAge(18)scala> s.getAgeres204: Int = 18

官方关于getter/setter的知识内容非常多,入门的时候这些案例可以先不用管,先从Java的角度出来能够使用scala进行开发即可。

@BeanProperty注解

如果对属性使用了@BeanProperty注解,那么就会自动生成getter/setter方法,但是需要注意的是,其并没有隐藏原来的属性,也就是说原来的属性还是可以直接访问的,并且其不可以使用private进行修饰。

看下面一个例子:

import scala.beans.BeanPropertyclass Student {  @BeanProperty var age:Int = 0 }

测试如下:

scala> var s = new Students: Student = Student@46482990scala> s.getAge()res205: Int = 0scala> s.setAge(18)scala> s.getAge()res207: Int = 18scala> s.ageres208: Int = 18

总结

上面啰嗦了很多,其实直接用下面的代码来进行说明就OK了:

/**  * scala面向对象第一章  *     关于对象的构造  *     类的构造(和java一样)  *  *   要运行一个scala的程序,不能在class来执行,需要在object中执行  *   你可以将这个object中的所有的字段、成员,都作为java中的静态的成员对待  *  *   在创建scala函数的时候,如果函数空参,我们可以在创建的时候省略掉这个(),但是在访问的时候也就不能使用带()的方式  *   反之我们既可以使用带(),也可以使用不带()的方式进行调用  *   ab.foreach(println)  *  *   为什么我们要在javabean对字段创建对应的getter和setter  *     带getter和setter的属性  *       就是为了程序的安全性?  *         屏蔽一些不合法的操作,提高程序的健壮性  */object _01ClazzFieldsOps {    def main(args: Array[String]): Unit = {        val person:Person = new Person()        person.increment()        println(person.currentAge())        println(person.currentAge)        val stu = new Student//        stu.age = -1        stu.setAge(-4)        stu.getNameval e = new Employee    }}class Person {    private var age:Int = 0 //创建一个类型为Int的私有化成员    def increment(): Unit = {        age += 1    }    def currentAge() = age}class Student {    private var age:Int = 15    private var name:String = "刘向前"    def setAge(a:Int):Unit = {        if(a < 1) {            throw new RuntimeException(s"你们家的孩子才是($a)岁呢")        }        age = a    }    def getAge = age    def getName = name}class Employee {    @BeanProperty var age:Int = 5}

构造器

关于构造器的说明和使用,直接看下面的测试代码就可以了,非常简洁:

package cn.xpleaf.bigdata.p2.constructor/**  * scala中的类的构造器说明  *   scala类的构造器分为主构造器和辅助构造器  *   其构造方式不同于java中的构造方式,public 类名(参数列表){},在scala中的构造器如何定义?  * scala中把类名后面的一对{}括起来的内容称为主构造器的函数体,默认的主构造器为空参构造器,  *   如何定义一个有参的主构造器呢?  *   就在类名后面写上函数的定义即可  *  *   当主构造器满足不了我们的需求之后,我们就可以创建更多的辅助构造器来配合我们的业务,辅助构造器如何创建?  *   def this  // 辅助构造器的函数名是this  *   注意,在辅助构造中的第一句话,必须是调用该类的主构造器或者其他辅助构造器,this(参数)  *     *   在一个类中只能有一个主构造器,可以有若干辅助构造器,在辅助构造器的第一句话,调用this  *  */object _02ConstructorOps {  def main(args: Array[String]): Unit = {    val p = new Person    // p.show()    println("=================================")    val stu = new Student("前向刘", 17)    stu.show()    println("=================================")    val s = new Student    println("=================================")    val s1 = new Student(true)  }}class Person {  private var name:String = "刘向前"  private var age:Int = 18/*  def Person(n:String, a:Int): Unit = {    name = n    age = a    println("这是scala中的构造器吗?")  }  def Person(): Unit = {    println("这是scala中的构造器吗?")  }*/  println("这是scala中的构造器吗?")  def show() = println(s"name is $name and age is $age")}class Student(var name:String, var age:Int) {  def this() {    this("刘银鹏", 25)    println("this is 辅助构造器")  }  private  var married:Boolean = false  def this(isMarried:Boolean) {    this()    married = isMarried    println(s"this($isMarried) 是另外一个构造器")  }  println("这是scala中的构造器吗?")  def show() = println(s"name is $name and age is $age")  // show() // 类构造时就会执行该方法,属性name和age也是默认有的,因为在主构造器中有}

内部类

直接看下面的一个完整案例:

package cn.xpleaf.bigdata.p2.inner/**  * 事物的内部还包含着事物,被包含的事物不能使用非常简单的成员变量来描述,只能使用更为复杂的结构去描述,  * 这个时候就用我们的内部类去定义  *  * 当多个变量重名的时候,遵循一个原则:局部优先    public class InnerClassOps {        public static void main(String[] args) {            Outer.Inner i = new Outer().new Inner();            i.show();        }    }    class Outer {        private int x = 5;        class Inner {            private int x = 6;            public void show() {                int x = 7;                System.out.println("Inner show: " + x);            }        }    }  this关键字,是本类的引用,当前类的实例的引用  外部类的引用使用外部类名.this  scala同样提供了一种较为简洁的写法,就是在我们的最外层大括号里写一个引用名称outer =>  在内部类中需要调用外部类的成员的时候,直接使用outer.成员代替外部类名.this  */object _03InnerClassOps {  def main(args: Array[String]): Unit = {    val outer = new Outer    val inner = new outer.Inner    inner.show()  }}class Outer { o =>  privateval x = 5  class Inner { i =>    private var x = 6    def show(): Unit = {      val x = 7      println("Inner show: " + this.x)  // 6      println("Inner show: " + i.x)     // 6      println("Inner show: " + Outer.this.x)  // 5      println("Inner show: " + o.x)           // 5    }  }}
构造器 方法 字段 时候 辅助 属性 成员 方式 函数 类名 这是 面的 私有 对象 生成 事物 内容 官方 注解 状态 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 喔噻互联网科技有限公司 奇酷互联网科技公司 腾讯科技 互联网女皇 润盈互联网科技 深圳艾佳互联网科技 金融科技和互联网金融 科技赋能互联网健康 深圳国际航运科技和互联网 互联网金融科技公司干啥的 互联网科技商业 互联网科技如何创业 为客找房互联网科技公司怎么样 广东工业互联网大赛深圳学泰科技 工业互联网科技创业 易企秀互联网科技是做什么的 济南小医互联网科技有限公司招聘 中国互联网公司的科技投入 北京品多多互联网科技有限公司 前海云享互联网科技 每日互联网科技新闻 湖南永感互联网科技有限公司 互联网科技公司税收优惠 互联网品科技 互联网科技英文 互联网 视角下的科技创新 昭通互联网科技选哪家 千方科技属于互联网企业吗 广州新华互联网科技学校电竞方面 高科技互联网发展前景如何 银川新华互联网科技学校招聘
0