Abstract vals && Abstract vars

Abstract vals && Abstract vars

在scala中抽象类和特质都可以定义抽象的成员变量。

Abstract vals && Abstract vars

abstract class Abstract {
  type T

  def transform(x: T): T

  val initial: T
  var current: T
}

class Concrete extends Abstract {
  override type T = String

  override def transform(x: T): T = x + x

  //在Java里这是final变量,所以必须要初始化赋值
  override val initial: T = "string"
  //在Java里这个private类型变量,在scala中可以yoga下划线赋值
  override var current: T = _
}

object Main9 {
  def main(args: Array[String]): Unit = {
    val c = new Concrete
    println(c.initial) //string
    println(c.current) //null
  }
}

如上的示例,定义两个抽象的成员变量,

val initial: T
var current: T

同时实现类实现抽象类的时候必须要赋值重写。在Java里看起来很怪,那么在Java里是如何实现的呢,通过javap反编译看一下

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft3>javap -p Abstract.class
Compiled from "test.scala"
public abstract class com.usoft3.Abstract {
  public abstract java.lang.Object transform(java.lang.Object);
  public abstract java.lang.Object initial();
  public abstract java.lang.Object current();
  public abstract void current_$eq(java.lang.Object);
  public com.usoft3.Abstract();
}

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft3>javap -p Concrete.class
Compiled from "test.scala"
public class com.usoft3.Concrete extends com.usoft3.Abstract {
  private final java.lang.String initial;
  private java.lang.String current;
  public java.lang.String transform(java.lang.String);
  public java.lang.String initial();
  public java.lang.String current();
  public void current_$eq(java.lang.String);
  public void current_$eq(java.lang.Object);
  public java.lang.Object current();
  public java.lang.Object initial();
  public java.lang.Object transform(java.lang.Object);
  public com.usoft3.Concrete();
}

其实在scala中定义的抽象字段在反编译后的java类中,其实就是抽象方法,

public abstract java.lang.Object initial();
public abstract java.lang.Object current();

那么也就不难理解了。


Initializing abstract vals

如下定义的抽象类中含有两个抽象变量

abstract class Abstract {
  val numerArg: Int
  val denomArg: Int
}

javap 反编译Abstract抽象类

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft4>javap -p Abstract.class
Compiled from "test.scala"
public abstract class com.usoft4.Abstract {
  public abstract int numerArg();
  public abstract int denomArg();
  public com.usoft4.Abstract();
}

scala中实现抽象类的方式最简单的如下,同时也必须重写抽象变量

new Abstract {
  override val denomArg: Int = 1
  override val numerArg: Int = 2
}

我们打印一下这个实现类的className

println(new Abstract {
  override val denomArg: Int = 1
  override val numerArg: Int = 2
}.getClass.getName)

com.usoft4.Main9$$anon$1,javap反编译

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft4>javap -p Main9$$anon$1.class
Compiled from "test.scala"
public final class com.usoft4.Main9$$anon$1 extends com.usoft4.Abstract {
  private final int denomArg;
  private final int numerArg;
  public int denomArg();
  public int numerArg();
  public com.usoft4.Main9$$anon$1();
}

反编译的Abstract抽象类中是没有定义的成员变量的,只是在抽象类的实现类中出现了父类的成员变量。

这其实就是Java中的匿名类的概念。

=================END=================

你可能感兴趣的:(Abstract vals && Abstract vars)