zoukankan      html  css  js  c++  java
  • Scala 学习笔记(2)之类和对象

    Scala 的类大抵和 Java 是类似的,简单的例子如下:

    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代码看看:

    import scala.reflect.ScalaSignature;
    
    @ScalaSignature(bytes="060112A!01020113	9Q*_"mCN34("A020217q*W1635;z}
    011C010107!	9!"D01	2505I21!B:dC2f27BA06	0531	e.37*fM")Q0201C0135051A(338jiz"22a04	03!01i21A0105%0101
    21"01240335i27PR5fY22,220106	0317UI!A06050307%sG17C0431010107I21A
    02275Lh)[3mI~#S-3513035u01"aB16
    05qA!01B+oSRDqAHf02020307A#A02yIEBa01	01!B23!2201C7z
    &,G163221	13501A2101222505=3103"0223"0104!22!02<bYV,07"022401	03923AC4fi6Kh)[3mIR	A03C03*012105!&0107bI22$v.T=GS26dG
    060233W!)A0513a01)01")
    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之后,也应该习以为常了吧。

    类部分虽然没有太多可说的地方,但是在对象上就有些许不同。Scala 中 object 用于构建 singleton 类型。

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

    在 Java 进行调用的话,就是

    Main.sayHi();
    

    之前在Java中写过Singleton代码的话,很容易猜出来具体的实现。反编译的代码:

    import scala.reflect.ScalaSignature;
    
    @ScalaSignature(bytes="0601e9Q!0102	0225	A!T1j]*	1!A04=K604H/37 0401A21aaB07020531)01B01E0123	!Q*Y5o'	9!020502f355	ABC01160325318-317b23	yAB0104B]f24VM320506#35!	AE0107y%t271636 250325AQ01F040502U	Qa]1z21&$22A06	0327]I!01070703	Us271636")
    public final class Main
    {
      public static void sayHi()
      {
        Main..MODULE$.sayHi();
      }
    }
    

    实现上来讲,只是多了一个 Main$ 类来实现具体的代码。

    有了静态成员,如何添加非静态成员?Scala给出的答案是 Companion Objects,也就是定义同名 class。

    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 中都定义了相同名称的成员,结果会如何呢?

    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

  • 相关阅读:
    今日总结
    今日总结
    今日总结
    k8s controller
    深入k8s:Informer使用及其源码分析
    理解 K8S 的设计精髓之 List-Watch机制和Informer模块
    Unix domain socket 简介
    Linux网络编程——端口复用(多个套接字绑定同一个端口)
    DPVS Tutorial
    dpvs route RTF_KNI
  • 原文地址:https://www.cnblogs.com/huys03/p/3994007.html
Copyright © 2011-2022 走看看