Java VS Scala(三)java接口(Interface)和scala特质(Trait)_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java VS Scala(三)java接口(Interface)和scala特质(Trait)

Java VS Scala(三)java接口(Interface)和scala特质(Trait)

 2018/6/15 21:21:02  shangboz  程序员俱乐部  我要评论(0)
  • 摘要:java8之前规定java接口只能有方法定义,不能有方法实现,java8之后增加了函数式接口,函数式接口可以有一个带实现的抽象方法,scala的特质跟java的接口有点类似,但是没有java代码那样的方法实现数量限制1.接口不会有构造器,特质可以有构造器,并且在实现类继承特质的时候,先要调用特质的构造器。2.接口中不能有未初始化的属性,且属性的修饰都是publicstaticfinal,特质中可以有未初始化的属性变量,即抽象字段3.类实现implements多个接口,且用逗号“,”隔开
  • 标签:Java 接口

java8之前规定java接口只能有方法定义,不能有方法实现,java8之后增加了函数式接口,函数式接口可以有一个带实现的抽象方法,scala的特质跟java的接口有点类似,但是没有java代码那样的方法实现数量限制

?

1.接口不会有构造器,特质可以有构造器,并且在实现类继承特质的时候,先要调用特质的构造器。

2.接口中不能有未初始化的属性,且属性的修饰都是public static final,特质中可以有未初始化的属性变量,即抽象字段

3.类实现implements多个接口,且用逗号“,”隔开,类继承extends多个trait且用with隔开。

4.Java中接口不能继承普通类,但是scala中特质可以extends class,并且该类成为所有继承trait的类的父类

实际的我们看例子

public interface JavaInterface {

    default void test(String agg) {
        System.out.println("Interface test");
    }
}

public class JavaInterfaceImpl implements JavaInterface {

    public void test2(String args) {
        test("Java interface test: " + args);

        System.out.println("Java interface impl test" + args );
    }

    public static void main(String args[]) {
        JavaInterfaceImpl javaInterface = new JavaInterfaceImpl();
        javaInterface.test("11111");
        javaInterface.test2("11111");
    }
}
运行结果:
Interface test
Interface test
Java interface impl test11111

?

?

trait ScalaTraitTest {

  val name:String//抽象字段
  println("name: "+name)//特质中构造器执行的语句

  def test(arg:String) ={
    println(s"Scala Trait test $arg")
  }

  def test2(arg:String, arg2:String) ={
    println(s"Scala Trait test2 $arg, $arg2")
  }

}

class ScalaTraitClass() extends {
  val name = "jack"
} with ScalaTraitTest {

  def test3(arg3:String) ={
  test(arg3)
  test2(arg3, "2222")
  println(s"Scala Trait class test 3 $arg3")

  }
}

object ScalaTraitClass {

  def main(args: Array[String]): Unit = {
    val classTest = new ScalaTraitClass

    classTest.test3("33333")
  }
}
运行结果:
name: jack
Scala Trait test 33333
Scala Trait test2 33333, 2222
Scala Trait class test 3 33333

?执行结果首先打印name: jack

?

通过上面的例子,我们反推一下具体的原因,还从class文件入手,通过反编译class文件查看其实际运行

java的函数式接口反编译后是一个abstract interface,其接口的本质没有改变

?

import java.io.PrintStream;

public abstract interface JavaInterface
{
  public void test(String agg)
  {
    System.out.println("Interface test");
  }
}
?但是scala的特质反编译后有两个class文件,ScalaTraiteTest.class和ScalaTraiteTest$class.class,ScalaTraiteTest$class.class是abstrac class,这里有$init$函数,就是一个构造器,ScalaTraiteTest.class是一个abstract interface

?

?

import scala.reflect.ScalaSignature;

public abstract interface ScalaTraitTest
{
  public abstract String name();
  
  public abstract void test(String paramString);
  
  public abstract void test2(String paramString1, String paramString2);
}
?

?

?

import scala.Predef.;
import scala.StringContext;
import scala.collection.mutable.StringBuilder;

public abstract class ScalaTraitTest$class
{
  public static void $init$(ScalaTraitTest $this)
  {
    Predef..MODULE$.println(new StringBuilder().append("name: ").append($this.name()).toString());
  }
  
  public static void test(ScalaTraitTest $this, String arg)
  {
    Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "Scala Trait test ", "" })).s(Predef..MODULE$.genericWrapArray(new Object[] { arg })));
  }
  
  public static void test2(ScalaTraitTest $this, String arg, String arg2)
  {
    Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "Scala Trait test2 ", ", ", "" })).s(Predef..MODULE$.genericWrapArray(new Object[] { arg, arg2 })));
  }
}
?

?

?我们再看其实现类ScalaTraitClass,ScalaTraitClass类确实实现了ScalaTraitTest接口,但是做了很多的事情,首先他的构造里调用了monospace;">ScalaTraitTest$class的构造器,这跟java类的构造流程一样;其次,ScalaTraitClass里面实现了接口定义的方法test和test2,但是内部实现是分别调用ScalaTraitTest$class的test和test2方法

?

import scala.Predef.;
import scala.StringContext;
import scala.reflect.ScalaSignature;

public class ScalaTraitClass
  implements ScalaTraitTest
{
  private final String name;
  
  public void test(String arg)
  {
    ScalaTraitTest.class.test(this, arg);
  }
  
  public void test2(String arg, String arg2)
  {
    ScalaTraitTest.class.test2(this, arg, arg2);
  }
  
  public String name()
  {
    return this.name;
  }
  
  public ScalaTraitClass()
  {
    ScalaTraitTest.class.$init$(this);
  }
  
  public void test3(String arg3)
  {
    test(arg3);
    test2(arg3, "2222");
    Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "Scala Trait class test 3 ", "" })).s(Predef..MODULE$.genericWrapArray(new Object[] { arg3 })));
  }
}

?

这样来看就清晰了很多,Scala的特质是把java的抽象类和接口特性揉在了一起,这样给编程带来了很大的灵活性也方便了很多。

发表评论
用户名: 匿名