Scala类详解
来源:互联网 发布:雅漾活泉保湿面膜 知乎 编辑:程序博客网 时间:2024/05/17 01:20
一个简单的Scala类:
当然还可以更简单的定义这个Person类:
如果不想由Scala生成getter和setter方法呢?
关于构造函数
如果喜欢传统的JavaBean风格的getter与setter,可以这样:
class Person { private var name: String = _ private var age = 0 def this(name: String, age: Int) { //实际上this是重载了主构造器,使用new Person()依然可以创建对象 this //默认构造器,即主构造器,class Person实际上省略了(),class Person()是主构造器 this.name = name this.age = age } def getName() = name //或则def getName = name def setName(name: String) { this.name = name }}object ClassTest { def main(args: Array[String]): Unit = { val a = new Person() println(a.getName()) val b = new Person("zero", 18) println(b.getName()) }}运行结果:
nullzero如注释,this方法是重载了主构造器,使用new Person()依然可以创建对象,在this方法中必须先调用this默认构造器,即主构造器,class Person实际上省略了(),class Person()是主构造器。和Java不一样,这里new Person()依然可以创建对象,如果想禁掉这种创建类的方式可以这样:
class Person private () { private var name: String = _ private var age = 0 def this(name: String, age: Int) { this this.name = name this.age = age } def getName() = this.name def setName(name: String) { this.name = name }}需要注意的是,在这种方式下定义类成员时必须要显式的指明初始值
当然还可以更简单的定义这个Person类:
class Person(val name: String, var age: Int, gender: String, number: Int) { def getNumber() = this.number;}object ClassTest { def main(args: Array[String]): Unit = { val b = new Person("zero", 18, "男", 7) b.age_=(20) println(b.name) println(b.age) }}使用jd-gui-windows-1.4.0(一下简称jd-gui)反编译Person.class后的结果如下:
public class Person{ private final String name; public String name(){ return this.name; } public int age(){ return this.age; } public void age_$eq(int x$1){ this.age = x$1; } public int getNumber(){ return this.number; } public Person(String name, int age, String gender, int number) {}}再使用javap –private Person.class反编译结果如下:
public class com.zero.clazz.Person { private final java.lang.String name; private int age; private final int number; public java.lang.String name(); public int age(); public void age_$eq(int); public int getNumber(); public com.zero.clazz.Person(java.lang.String, int, java.lang.String, int);}结合两个工具的反编译结果分析:Scala自动将这个类变成了public,在Scala中任何没有标记为private或则protected的数据都默认为public。Scala将声明为var的age成员用private修饰,并对外提供getter和setter方法用以取值和赋值(在Scala中,getter和setter分别叫做age和age_=,默认的getter和setter是由Scala自动生成),将声明为val的成员用private final修饰,并对外提供getter方法用以取值。对于既不是var也不是val的成员,如果在类中没有被使用,那么就忽略了该字段,如果被使用了(只能够取值不能赋值),那个该字段就晋升为类的成员,被private final修饰。
如果不想由Scala生成getter和setter方法呢?
class Person(val name: String) { private var age = 0 private[this] var gender: String = "男"}javap反编译结果:
public class com.zero.clazz.Person { private final java.lang.String name; private int age; private java.lang.String gender; public java.lang.String name(); private int age(); private void age_$eq(int); public com.zero.clazz.Person(java.lang.String);}可以发现,private [this] var gender类似于定义对象的私有字段,其他同一个类的对象也无法访问到,Scala不会生成getter或setter方法。
关于构造函数
class Person(val name: String, var age: Int, gender: String) { private var firstName: String = _ def this(name: String, age: Int, gender: String, firstName: String) { this(name, age, gender) this.firstName = firstName println("construct_02") } println("construct_01") override def toString(): String = { age + " zero " + firstName }}object ClassTest { def main(args: Array[String]): Unit = { val a = new Person("zero", 18, "男") println(a) val b = new Person("zero", 18, "男", "007") println(b) }}运行结果:
construct_0118 zero nullconstruct_01construct_0218 zero 007jd-gui反编译后的Person:
public class Person{ private final String name; private String firstName; public String name(){ return this.name; } public int age(){ return this.age; } public void age_$eq(int x$1){ this.age = x$1; } private String firstName(){ return this.firstName; } private void firstName_$eq(String x$1){ this.firstName = x$1; } public Person(String name, int age, String gender, String firstName){ this(name, age, gender); firstName_$eq(firstName); Predef..MODULE$.println("construct_02"); } public Person(String name, int age, String gender){ Predef..MODULE$.println("construct_01"); } public String toString(){ return new StringBuilder().append(age()).append(" zero ").append(firstName()).toString(); }}javap反编译后的结果:
public class com.zero.clazz.Person { private final java.lang.String name; private int age; private java.lang.String firstName; public java.lang.String name(); public int age(); public void age_$eq(int); private java.lang.String firstName(); private void firstName_$eq(java.lang.String); public java.lang.String toString(); public com.zero.clazz.Person(java.lang.String, int, java.lang.String); public com.zero.clazz.Person(java.lang.String, int, java.lang.String, java.lang.String);}发现实际上scala生成了两个构造函数,主构造函数Person(String name, int age, String gender),辅助构造器也调用了主构造函数,主构造函数会将类{}里面的语句纳入到其方法类。
如果喜欢传统的JavaBean风格的getter与setter,可以这样:
class Person(@BeanProperty val name: String, @BeanProperty var age: Int, @BeanProperty gender: String) {}javap反编译结果:
public class com.zero.clazz.Person { private final java.lang.String name; private int age; public java.lang.String name(); public int age(); public void age_$eq(int); public void setAge(int); public java.lang.String getName(); public int getAge(); public com.zero.clazz.Person(java.lang.String, int, java.lang.String);}可以发现将会生成四个方法,除了Scala默认的setter和getter方法,还有JavaBean风格的getter与setter方法。
0 0
- Scala详解---------类
- Scala类详解
- scala集合类详解
- Scala详解---------快速入门Scala
- Scala详解---------快速入门Scala
- Scala详解--------基础知识详解
- Scala详解---------对象
- Scala详解----------继承
- Scala详解---------继承深入
- SCALA的例子详解
- Scala集合类型详解
- Scala--样例类(case)详解
- Scala Trait详解
- Scala运算符详解
- Scala 使用详解
- Linux 安装Scala 详解
- scala中的json详解
- 十. Scala函数详解
- iOS地球坐标,火星坐标,百度坐标互转
- MapReduce中的两表join几种方案简介
- <Test-Driven Development with Python>学习笔记 第一部分 测试驱动开发基础
- 【设计模式】建造者模式
- 离散--第三章
- Scala类详解
- 无法修改linux密码Authentication token manipulation error 问题解决
- perl-标准输入与输出
- linux 下音频的录制与播放测试例子
- 计算机组成原理
- 秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量
- C语言基础总结-++ -- += -=
- JAVA练级之路(一)--- JAVA环境配置
- 数据结构基础--线性表操作