【图文详细 】Scala——类

版权声明:版权声明:本文为博主原创文章,转载请附上博文链接! https://blog.csdn.net/qq_42246689/article/details/85131245

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、里面的属性不能写修饰符 

猜你喜欢

转载自blog.csdn.net/qq_42246689/article/details/85131245