跳至主要内容

Scala 中的类与对象

在本教程中,您将学习 Scala 面向对象编程的基本概念:类与对象。
· 8分钟 阅读

使用 AI 探索

DataCamp 最近上线了他们的首门 Scala 课程:Introduction to Scala。欢迎查看!

另外,也请查看以下教程:

简介

面向对象概念示意图
来源

一般来说,面向对象编程(OOP)由类和对象组成,旨在实现现实世界的实体,如多态、继承等。

OOP 使开发更快、更低成本,并且具有更好的软件可维护性。其“魔力”的主要原因在于其支持的众多特性;您拥有可以在未来按需轻松复用的类与对象,这与缺少类和对象的程序形成对比。其结果是更高质量的软件,并且可以通过新增方法和属性进行扩展。

举个例子:您有一家汽车展厅;每隔几个月就会有新车发布。要告知受众其名称和功能,您需要从零定义新方法和属性。而如果您有一个包含 car 类的面向对象程序,那么您只需为那辆新车新增一个对象,由它携带车辆信息来调用类的方法和属性。

可以把类看作对象的表示或设计图。类通常有自己的方法(行为)和属性。

属性是区分各个对象的独立实体,决定了对象的各种特性。另一方面,方法更像编程中的函数运作方式。它们决定了类实例的工作方式。正是因为方法(行为),对象才具备可被操作的能力。

来源

上图能帮助您更直观地理解面向对象编程的流程,或者更具体地说,类的样子。在上图中,有一个 class car,它有 attributes: fuel, max speed,并且可以有更多属性,比如 model、make 等。它还有不同的methods,如 refuel()、getFuel()、setSpeed(),以及一些额外的方法,比如 change gear、start the engine、stop the engine 等。

因此,当您谈到一辆具体的车时,您会有一个对象,也就是类的一个实例。

现在,让我们来谈谈 Scala 中的面向对象编程。

Scala 中的类与对象

与 C++ 和 Java 类似,Scala 中的面向对象编程基本遵循相同的约定。它有定义 classes 和 objects 的概念,以及类中的 constructors。这基本上就是 Scala 面向对象编程的全部。

类的声明

class Class_name{
// methods and attributes
}

Scala 中的类由关键字 class 加上类名来定义,一般类名以大写字母开头。有一些可选的关键字可以用于 Scala 类声明,如:class-name,应以大写字母开头;superclass,即在 extend 关键字之后的父类名;traits,即在 extend 关键字之后由类实现的以逗号分隔的特质列表。

Scala 中的类只能继承一个父类,这意味着 Scala 不支持多重继承。不过,可以通过使用 Traits 来实现类似效果。

最后,Scala 中类的主体由花括号 {} 包围。

// Name of the class is Car
class Car
{

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

    // Class method
    def Display()
    {
        println("Make of the Car : " + make);
        println("Model of the Car : " + model);
        println("Fuel capacity of the Car : " + fuel);
    }
}
object Main  
{

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

        // Class object
        var obj = new Car();
        obj.Display();
    }
}

您可以将以上代码保存为 class.scala,并在终端以 scala class.scala 运行,您应能看到如下输出。

输出

不过,上述代码并未充分利用面向对象程序的优势。因为无论您运行多少次,其输出都会相同。您在类中定义了静态变量,这些变量的值将保持不变,即便您创建无数个新对象也是如此。换言之,您不能指望它为您提供梅赛德斯-奔驰或法拉利的详细信息。

Scala 中的构造函数

构造函数主要用于初始化对象状态。对象的初始化发生在对象创建时,并且只会被调用一次。

Scala 中有两种构造函数:Primary 和 Auxiliary。在本教程中,您将学习主构造函数(来源:O'Reilly)。

class Class_name(Parameter_list){
// methods, attributes
}

主构造函数与类共享同一个主体,它在类定义时隐式创建。从类定义开始,贯穿整个类体。此外,当 Scala 程序中只有一个构造函数时,它被称为主构造函数。主构造函数可以定义为零个、一个或多个参数。

那么,让我们沿用之前的例子,这一次加入主构造函数的特性并观察其效果。

另外,您还将学习类的一个新特性:一个类可以有多个对象或实例,且它们彼此独立。

// Name of the class is Car
class Car(make: String, model: String, fuel: Int)
{

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

object Main

{

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

        // Multiple Class object
        var obj1 = new Car("BMW", "X7", 40);
        var obj2 = new Car("Mercedes Benz", "S350D", 50);
        obj1.Display();
        obj2.Display();
    }
}

我们快速看一下输出:

输出

很棒,不是吗?借助构造函数,您能够生成更有效的结果。

在 Scala 中声明对象

在 Scala 中声明对象也可称为实例化类或调用类。与类相似,对象同样是面向对象编程的基本单位。

一个对象可以由三个特征组成(来源:GeeksforGeeks):

  • State: 对象的属性用于表示对象,也反映对象的特性。
  • Behavior: 对象的方法用于表示对象,也反映对象与其他对象交互时的响应。
  • Identity: 为对象赋予唯一名称,使一个对象能够与其他对象交互。

以狗(Dog)为对象,参见下图了解其标识、状态和行为。

示意图
(来源)

所有实例或对象共享类的属性和方法。正如您在这里学到的,一个类可以有多个对象。不过,每个对象的状态或取值是唯一的。

最后,您将编写一段代码,它把主构造函数、类变量、属性和方法全部结合在一起。

下面是类 Motorcycle 中这些组件组合在一起的图示。

类的组成

下面的代码基本不言自明;在高层次上,它会检查摩托车发动机是 on 还是 off。起初,发动机处于关闭状态,程序会通知您其状态并将其开启。

class Motorcycle(make:String,color:String) {


       var engineState: Boolean = false;

       def startEngine() {
          if (engineState == true){
            println("The engine is already on.");
          }
          else {
            engineState = true
            println("The engine is now on.");
         }
       }

       def showAtts() {
         println("This motorcycle is a "+ color + " " + make);
         if (engineState == true){
           println("The engine is on.");
         }
         else{
            println("The engine is off.");
         }
      }

}
object Main
{
    def main (args: Array[String])
    {
        var m = new Motorcycle("BMW K 1600 GTL","White");
        println("Calling showAtts...");
        m.showAtts();
        println("------");
        println("Starting engine...");
        m.startEngine();
        println("------");
        println("Calling showAtts...");
        m.showAtts();
        println("------");
        println("Starting engine...");
        m.startEngine();
    }
}
示意图

恭喜!

恭喜您完成本教程。

您现在已经知道如何在 Scala 中声明类和方法、实例化对象、设置其属性并调用实例方法。这些概念不仅对 Scala 有用,对其他编程语言也同样适用。

面向对象编程概念既有趣又非常强大。它为您的代码增添新的维度,使其可复用。随着程序规模变大,代码的复杂度也会增加。面向对象编程中有大量内容,如继承、多态、实例方法。另一个强大特性是单例。良好的设计原则有助于让您的代码更加结构化、可读。若想进一步了解设计模式,可以考虑阅读这本书。

欢迎在下方评论区就本教程提出任何问题。

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

主题