1、Scala 类
Scala 的类与 Java、C++的类比起来更简洁,学完之后你会更爱 Scala!!!
1.1、定义类
定义一个 Student 类:
package com.mazh.scala.day2.oop
// 在 Scala
中,类并不用声明为 public 。
// 在 Scala
文件中,文件名可以不用和类名一致
//Scala
源文件中可以包含多个类,所有这些类都具有公有可见性
class Person {
// 用 val
修饰的变量是只读属性,有 getter
但没有 setter
// (相当与 Java
中用 final
修饰的变量)
val id = "100"
/**
* 作者: 李涛: https://blog.csdn.net/qq_42246689
*/
// 用 var
修饰的变量既有 getter
又有 setter
var age: Int = 33
// 类私有字段 , 只能在 当前 类的内部或伴生对象中使用 private var name: String = "黄渤"
// 对象私有字段 , 访问权限更加严格的, Person
类的方法只能访问到当前对象的字段
// 伴生对象都不能访问 private[this] val nickname = "影帝"
}
通过反编译工具反编译之后看到:
package com.mazh.scala.util;
public class Person {
private final String id = "100";
private int age = 33;
private String name = "黄渤";
private final String nickname = "影帝";
// 相当于 id属性的 getId() 方法
public String id() {
return this.id;
}
// 相当与 age属性的 getAge() 方法
public int age() {
return this.age;
}
// 相当与 age属性的 setAge方法
public void age_$eq(int x$1) {
this.age = x$1;
}
// name属性的私有 get方法
private String name() {
return this.name;
}
// name属性的私有 set方法
private void name_$eq(String x$1) {
this.name = x$1;
}
}
通过 JDK 自带的反编译工具反编译:
C:\IdeaProjects-2017-02-07\ScalaTest\out\production\ScalaTest\com\mazh\scala\day2\oop>java p -private Person
警告: 二进制文件 Person 包含
com.mazh.scala.day2.oop.Person
Compiled from "Person.scala"
public class com.mazh.scala.day2.oop.Person {
private final java.lang.String id;
private int age;
private java.lang.String name;
private final java.lang.String nickname;
public java.lang.String id();
public int age();
public void age_$eq(int);
private java.lang.String name();
private void name_$eq(java.lang.String);
public com.mazh.scala.day2.oop.Person();
}
下面这张图给出了 setter 和 getter 方法的生成关系:
1.2、定义构造器
注意:主构造器会执行类定义中的所有语句
定义一个 Student 类:
package com.mazh.scala.day2.oop
import java.io.IOException
/**
* 每个类都有主构造器,主构造器的参数直接放置类名后面,与类交织在一起 * 主构造器会执行类定义中的所有语句
* 当在创 建对象时,需要进行相关初始化操作时,可以将初始化语句放在类体中
* 同样也可以在类中添加或重写相关方法
*/
class Student(val name: String, val age: Int){
println("执行主构造器")
try {
println("读取文件")
throw new IOException("io exception")
} catch {
case e: NullPointerException => println("打印异常 Exception : " + e)
case e: IOException => println("打印异常 Exception : " + e)
} finally {
println("执行 finally 部分")
}
private var gender = "male"
// 用 this关键字定义辅助构造器
def this(name: String, age: Int, gender: String){
// 每个辅助构造器必须以主构造器或其他的辅助构造器的调用开始
this(name, age)
println("执行辅助构造器")
this.gender = gender
}
}
定义辅助构造器:
如果禁用掉了主构建器(使用 private 声明),则必须使用辅助构造函数来创建对象。
辅助构造函数具有两个特点:
1、辅助构建器的名称为 this,Java 中的辅助构造函数与类名相同,这常常会导致修改类名 时出现不少问题,scala 语言避免了这样的问题;
2、调用辅助构造函数时,必须先调用主构造函数或其它已经定义好的构造函数。
定义一个 Queen 类:
package com.mazh.scala.day2.oop
// 构造器参数可以不带 val或 var ,
// 如果不带 val或 var的参数至少被一个方法所使用 , 那么它将会被提升为字段
// 在类名后面加 private就变成了私有的 ,相当于 禁用了主构造器
class Queen private(val name: String, prop: Array[String], private var age: Int = 18){
println(prop.size)
//prop被下面的方法使用后, prop就变成了不可变的 对象私有字段,
// 等同于 private[this] val prop
// 如果没有被方法使用该参数将不被保存为字段
// 仅仅是一个可以被主构造器中的代码访问的普通参数
def description = name + " is " + age + " years old with " + prop.toBuffer
}
object Queen{
def main(args: Array[String]) {
// 私有的构造器,只有在其伴生对象中使用
val q = new Queen("刘亦菲", Array("女神", "女神经"), 20)
println(q.description())
}
}
总结: 主构造方法:
1、与类名交织在一起
2、主构造方法运行,导致类名后面的大括号里面的代码都会运行
辅助构造方法:
1、名字必须叫 this
2、必须以调用主构造方法或者是其他辅助构造方法开始
3、里面的属性不能写修饰符