跳至主要内容

Scala 特质(Traits)

通过语法示例学习 Scala 中特质(trait)的用法。
· 6分钟 阅读

使用 AI 探索

DataCamp 近期上线了首门 Scala 课程:Introduction to Scala。欢迎查看!

您或许也会对以下教程感兴趣:

简介

特质(Trait)是面向对象编程中常用的概念,可通过一组方法扩展类的功能。

Traits 在理念上类似于 Java 编程语言中的接口。与类不同,Scala 的 trait 不能被实例化,也没有参数。然而,您可以通过类和对象来继承(扩展)它们。也就是说,trait 提供一组用于为类执行某种行为的方法/函数,并期望该类实现一组方法来对这种行为进行参数化。

用于定义对象的 trait 是由一组可被不同类使用的方法混合而成,而无需多重继承。不过,也可能出现两个 trait 含有同名方法(命名冲突),并且需要由同一个类使用的情况,此时必须显式解决歧义。

Traits 可以同时拥有抽象与非抽象的方法和字段作为其成员。在 trait 中未进行初始化的方法为抽象方法,而已初始化的方法为非抽象方法。对于抽象方法,将由实现该 trait 的类负责初始化。

现在,让我们通过一些示例快速理解 Scala 的 traits!

Scala Trait 语法

Scala trait 的语法很直接,由关键字 trait 加上 trait 名称构成。

trait Trait_Name{
// Variables
// Methods
}
scala trait 语法


如上所示,定义了名为 DataCamp 的 trait,其中未定义任何变量或方法。

接下来我们看一个简单示例,以更清楚地了解它在程序中的工作方式。

如简介所述,Scala 的 Traits 通过 extends 关键字由类来继承。

class Scala_Tutorial extends DataCamp{
// Variables
// Methods
}

我们来定义一个名为 Scala_Course 的 trait,它将被类 DataCamp 继承。在 trait 中定义一个抽象方法 scala(),并在 DataCamp 类中对其进行定义。

trait Scala_Course{  
    def scala()  
}  

class DataCamp extends Scala_Course{  
    def scala(){  
        println("DataCamp has recently launched there first Scala course")  
    }  
}  

object Main{  
    def main(args:Array[String]){  
        var a = new DataCamp()  
        a.scala()  
    }  
}

现在我们来运行以上代码。

示例


在上述示例中,方法 scala() 是抽象方法,因此其声明是在继承该 trait 的类中完成的。

但如果某个方法(非抽象)已经在 trait 中实现了呢?在这种情况下,扩展该 trait 的类无需再实现已在 trait 中实现的方法。

我们用一个小例子来理解。

trait BMW{

    // trait variables
    var make: String = "BMW"
    var model: String = "X7"
    var fuel: Int = 40

    // trait method: NON-ABSTRACT
    def Display()
    {
        println("Make of the Car : " + make);
        println("Model of the Car : " + model);
        println("Fuel capacity of the Car : " + fuel);
    }
}


class Car extends BMW{
    // class variables
    var make1: String = "Mercedes Benz"
    var model1: String = "S350D"
    var fuel1: Int = 50

    // Class method
    def Merc_Specs()
    {
        println("Make of the Car : " + make1);
        println("Model of the Car : " + model1);
        println("Fuel capacity of the Car : " + fuel1);
    }
}

object Main  
{

    // Main method
    def main(args: Array[String])  
    {

        // Class object
        var obj = new Car();
        println("Calling the Class Method")
        obj.Merc_Specs();
        println("Calling the Trait Method")
        obj.Display();
    }
}

我们来运行上述代码:

示例


现在您已经理解了 abstract 与 non-abstract 方法之间的区别,接下来看看当未在继承或扩展它的类中实现 abstract 方法时,会出现什么问题。

我们使用相同的示例来说明这一点。

trait Scala_Course{  
    def scala()  
}  

class DataCamp extends Scala_Course{  
    def print(){  
        println("Error: Class DataCamp needs to be Abstract")  
    }  
}  

object Main{  
    def main(args:Array[String]){  
        var a = new DataCamp()  
        a.print()  
    }  
}

运行以上代码会产生如下错误,因为您没有在继承该 trait 的类中定义 trait 方法 scala()(抽象)。

示例

要让上述代码正常工作,有两种可能的解决方案:

  • 在 DataCamp 类中定义 scala() 方法,或
  • 将 DataCamp 类定义为 abstract。

本教程的最后一个主题是如何在一个类中继承多个 trait。我们来快速完成它。

trait A{
// methods
}
trait B{
// methods
}
class C extends A with B{
}
trait BMW{


    var make: String = "BMW"
    var model: String = "X7"
    var fuel: Int = 40
}

trait Merc{


    var make1: String = "Mercedes Benz"
    var model1: String = "S350D"
    var fuel1: Int = 50


}



class Car extends BMW with Merc{

    def BMW_Specs()
    {
        println("Make of the Car : " + make);
        println("Model of the Car : " + model);
        println("Fuel capacity of the Car : " + fuel);
    }


    def Merc_Specs()
    {
        println("Make of the Car : " + make1);
        println("Model of the Car : " + model1);
        println("Fuel capacity of the Car : " + fuel1);
    }

}


object Main  
{

    // Main method
    def main(args: Array[String])  
    {

        // Class object
        var obj = new Car();
        println("Calling the BMW Trait")
        obj.BMW_Specs();
        println();
        println("Calling the Merc Trait")
        obj.Merc_Specs();
    }
}

最后,让我们运行以上代码。

示例

恭喜!

恭喜您完成本教程。

您现在已经了解了编程中的 Traits 是什么,以及如何在 Scala 中使用它。一个不错的练习是:当抽象方法未在继承它的类中定义时,如何给出解决方案。试着为此编写代码,并查看是否能在没有编译错误的情况下运行。小提示:您或许可以看看 Scala 中的抽象类。

如有与本教程相关的问题,欢迎在下方评论区留言。

最后别忘了学习 DataCamp 的全新 Scala 课程:Introduction to Scala。

主题