Scala 學習筆記(2)之類和對象

Scala 的類大抵和 Java 是相似的,簡單的例子以下:html

class MyClass {
    var myField : Int = 0;

    
    def this(value : Int) = {
        this();
        this.myField = value;
    }


    def getMyField() : Int = {
    	return this.myField;  
    }

    def addToMyField(value : Int) {
        this.myField += value;
    }
}

若是好奇,能夠把編譯後的代碼反編譯成Java代碼看看:java

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\00112A!\001\002\001\013\t9Q*_\"mCN\034(\"A\002\002\017q*W\016\035;z}\r\0011C\001\001\007!\t9!\"D\001\t\025\005I\021!B:dC2\f\027BA\006\t\005\031\te.\037*fM\")Q\002\001C\001\035\0051A(\0338jiz\"\022a\004\t\003!\001i\021A\001\005\b%\001\001\r\021\"\001\024\003\035i\027PR5fY\022,\022\001\006\t\003\017UI!A\006\005\003\007%sG\017C\004\031\001\001\007I\021A\r\002\0275Lh)[3mI~#S-\035\013\0035u\001\"aB\016\n\005qA!\001B+oSRDqAH\f\002\002\003\007A#A\002yIEBa\001\t\001!B\023!\022\001C7z\r&,G\016\032\021\t\0135\001A\021\001\022\025\005=\031\003\"\002\023\"\001\004!\022!\002<bYV,\007\"\002\024\001\t\0039\023AC4fi6Kh)[3mIR\tA\003C\003*\001\021\005!&\001\007bI\022$v.T=GS\026dG\r\006\002\033W!)A\005\013a\001)\001")
public class MyClass
{
  private int myField = 0;

  public int myField() { return this.myField; } 
  public void myField_$eq(int x$1) { this.myField = x$1; }


  public int getMyField()
  {
    return myField();
  }

  public void addToMyField(int value) {
    myField_$eq(myField() + value);
  }

  public MyClass()
  {
  }

  public MyClass(int value)
  {
    this();
    myField_$eq(value);
  }
}

除了ScalaSignature,其餘部分再熟悉不過了。只是Scala在語法上稍做了改變,在學習了golang和swift以後,也應該習覺得常了吧。golang

類部分雖然沒有太多可說的地方,可是在對象上就有些許不一樣。Scala 中 object 用於構建 singleton 類型。swift

object Main {
	def sayHi() {
		println("Hi!");
	}
}

在 Java 進行調用的話,就是學習

Main.sayHi();

以前在Java中寫過Singleton代碼的話,很容易猜出來具體的實現。反編譯的代碼:this

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001e9Q!\001\002\t\002\025\tA!T1j]*\t1!A\004=K6\004H/\037 \004\001A\021aaB\007\002\005\031)\001B\001E\001\023\t!Q*Y5o'\t9!\002\005\002\f\0355\tABC\001\016\003\025\0318-\0317b\023\tyAB\001\004B]f\024VM\032\005\006#\035!\tAE\001\007y%t\027\016\036 \025\003\025AQ\001F\004\005\002U\tQa]1z\021&$\022A\006\t\003\027]I!\001\007\007\003\tUs\027\016\036")
public final class Main
{
  public static void sayHi()
  {
    Main..MODULE$.sayHi();
  }
}

實現上來說,只是多了一個 Main$ 類來實現具體的代碼。scala

有了靜態成員,如何添加非靜態成員?Scala給出的答案是 Companion Objects,也就是定義同名 class。htm

object Main {
	def sayHi() {
		println("Hi!");
	}
}

class Main {
    def sayHelloWorld() {
        println("Hello World");
    }
}

 

這樣一來,Main既支持靜態方式調用,也支持實例化。其實在 Java 中只是一個類,包含了靜態成員和非靜態成員而已。  對象

public class Main
{
  public static void sayHi()
  {
    Main..MODULE$.sayHi();
  }

  public void sayHelloWorld()
  {
    Predef..MODULE$.println("Hello World");
  }
}

 

能夠考慮一種狀況,object 和 class 中都定義了相同名稱的成員,結果會如何呢?blog

object Main {
	def sayHi() {
		println("Hi!");
	}
}

class Main {
    def sayHelloWorld() {
        println("Hello World");
    }

    def sayHi() {
    	println("non-static hi!")
    }
}

編譯沒有報錯,結果是靜態成員沒法訪問了。

 

error: non-static method sayHi() cannot be referenced from a static context
        Main.sayHi();
            ^
1 error

 

靜態方法被隱藏了,能夠經過反編譯來驗證。

 

public class Main
{
  public void sayHelloWorld()
  {
    Predef..MODULE$.println("Hello World");
  }

  public void sayHi() {
    Predef..MODULE$.println("non-static hi!");
  }
}

 

實際生成的代碼中並不包含靜態成員。有沒有辦法訪問以前的靜態成員呢?能夠試試下面的代碼:  

Main$.MODULE$.sayHi();

固然,以上是Java中調用的狀況,在 Scala 中是能夠區分兩個sayHi的。

object UseInScala {
	def main(args: Array[String]) {
		Main.sayHi();
		var main = new Main();
		main.sayHi();
	}
}

  輸出:

> scala UseInScala 
Hi!
non-static hi!

  

從這些方面來看,Scala 的代碼是極容易引入到 Java 中的,下一步可能會花些功夫在 Scala 的學習和應用上。

 

 

[1]http://tutorials.jenkov.com/scala/singleton-and-companion-objects.html

相關文章
相關標籤/搜索