美文网首页
Scala编程基础24:Scala特征

Scala编程基础24:Scala特征

作者: 金字塔下的小蜗牛 | 来源:发表于2020-04-09 08:14 被阅读0次

    Scala Trait(特征)相当于Java中的接口,实际上它比接口的功能还要强大。与接口不同的是,Trait可以定义属性和方法的实现。一般情况下,Scala的类只能继承单一父类,但是可以继承多个Trail。Trait定义方式与类的定义类似,但是使用trait关键字,

    1.定义Trait

    下面的例子演示了Trait的定义:

    trait Equal {
        def isEqual(x:Any):Boolean;
        def isNotEuqal(x:Any):Boolean=!isEqual(x);
    }
    

    以上Trait(特征)由两个方法组成:isEqual和isNotEuqal。isEqual方法没有定义方法的实现,isNotEqual定义了方法的实现。子类继承Trait可以实现未实现的方法。这一点Scala Trait更像Java的抽象类(抽象类:含有抽象方法的类;接口:全部方法都是抽象方法)。

    2.使用Trait

    下面的例子演示了trait的使用:

    trait Equal {
        def isEqual(obj:Any):Boolean;
        def func1()={
            "from trait Equal";
        }
    }
    trait NotEqual {
        def isNotEqual(obj:Any):Boolean;
        def func2()={
            "from trait NotEqual";
        }
    }
    class Point(xc:Int,yc:Int) extends Equal with NotEqual {
        var x:Int = xc;
        var y:Int = yc;
        def isEqual(obj:Any) = {
            obj.isInstanceOf[Point] && 
            obj.asInstanceOf[Point].x == x &&
            obj.asInstanceOf[Point].y == y;
        }
        def isNotEqual(obj:Any) = {
            !(obj.isInstanceOf[Point] && 
            obj.asInstanceOf[Point].x == x &&
            obj.asInstanceOf[Point].y == y);
        }
        override def func2() = {
            "from class Point";
        }
    }
    object Test1 {
        def main(args:Array[String]) {
            val p1 = new Point(2,3);
            val p2 = new Point(2,4);
            println("p1("+p1.x+","+p1.y+")");
            println("p2("+p2.x+","+p2.y+")");
            println("p1.isEqual(p1) = "+p1.isEqual(p1));
            println("p1.isEqual(p2) = "+p1.isEqual(p2));
            println("p2.isNotEqual(p1) = "+p2.isNotEqual(p1));
            println("p2.isNotEqual(p2) = "+p2.isNotEqual(p2));
            println("p1.func1 "+p1.func1);
            println("p1.func2 "+p1.func2);
        }
    }
    

    编译并执行上述代码,输出结果如下:

    E:\Test>scalac Test1.scala
    E:\Test>scala Test1
    p1(2,3)
    p2(2,4)
    p1.isEqual(p1) = true
    p1.isEqual(p2) = false
    p2.isNotEqual(p1) = true
    p2.isNotEqual(p2) = false
    p1.func1 from trait Equal
    p1.func2 from class Point

    根据上述代码,需要注意以下几点:

    • Scala的类继承Trait使用extends关键字,多个Trait之间使用with连接;
    • Trait中的抽象方法(没有实体)必须要重写,如isEqual和isNotEqual;
    • Trait中的非抽象方法(有实体)可以不重写,如func1;但是如果重写,需要使用override关键字修饰,如func2;

    3.Trait构造顺序

    Trait也可以有构造器,由字段的初始化和其他语句构成。这些语句在继承该Trait的对象构造时都会被执行。

    构造器的执行顺序如下:

    • 调用超类的构造器
    • 调用特征的构造器
    • 调用子类的构造器

    其中特征的构造需要注意以下几点:

    • 特征由左到右被依次构造
    • 每个特征中,父特征先被构造
    • 如果多个特征共有一个父特征,父特征不会被重复构造
    • 所有的特征被构造完毕,子类才被构造

    下面的例子演示了各种构造器的执行顺序:

    trait duobianxing {
        println("construct trait duobianxing");
    }
    trait lingxing extends duobianxing {
        println("construct trait lingxing");
    }
    trait juxing extends duobianxing {
        println("construct trait juxing");
    }
    trait zhengfangxing extends lingxing with juxing {
        println("construct trait zhengfangxing");
    }
    class tuxing {
        println("construct class tuxing");
    }
    class mySquare extends tuxing with zhengfangxing {
        println("construct class mySquare");
    }
    object Test2 {
        def main(args:Array[String]) {
            var square:mySquare = new mySquare();
            println("this is main method");
        }
    }
    

    编译并执行上述代码,输出结果如下:

    E:\Test>scalac Test2.scala
    E:\Test>scala Test2
    construct class tuxing
    construct trait duobianxing
    construct trait lingxing
    construct trait juxing
    construct trait zhengfangxing
    construct class mySquare
    this is main method

    上面的例子中:

    • 定义特征:多边形duobianxing
    • 定义特征:菱形lingxing和矩形juxing,继承自:多边形duobianxing
    • 定义特征:正方形zhengfangxing,继承自:菱形lingxing和矩形juxing
    • 定义类:图形tuxing
    • 定义子类:mySquare,继承自:图形tuxing和正方形zhengfangxing
    • 当实例化mySquare类对象时,就会按照前面的构造器执行顺序来执行构造。

    相关文章

      网友评论

          本文标题:Scala编程基础24:Scala特征

          本文链接:https://www.haomeiwen.com/subject/oaskdhtx.html