Scala 类和对象

  • 类和对象

    本章将指导您如何在Scala编程中使用类和对象。类是对象的蓝图。一旦定义了一个类,就可以使用关键字new从类蓝图创建对象。通过该对象,您可以使用已定义类的所有功能。 下图以Student类为例演示了类和对象,其中包含成员变量(name和rollNo)和成员方法(setName()和setRollNo())。最后,所有人都是类的成员。类是一个蓝图,这里的对象是真实的。在下图中,“Student”是一类,而“ZhangSan”,“LiSi”和“WangWu”是“Student”类的对象,它们具有name和rollNo
    obj
  • 基本类

    以下是在Scala中定义基本类的简单语法。此类定义了两个变量x和y以及一个方法:move,它不返回值。类变量被称为,类和方法的字段称为类方法。类名用作可以使用许多参数的类构造函数。上面的代码定义了两个构造函数参数xc和yc;它们在整个类中中都是可见的。
    
    class Point(xc: Int, yc: Int) {
       var x: Int = xc
       var y: Int = yc
    
       def move(dx: Int, dy: Int):Unit= {
          x = x + dx
          y = y + dy
          println ("Point x location : " + x);
          println ("Point y location : " + y);
       }
    }
    
    如本章前面所述,您可以使用关键字new创建对象,然后可以访问类字段和方法,如下例所示-
    
    import java.io._
    
    class Point(val xc: Int, val yc: Int) {
       var x: Int = xc
       var y: Int = yc
       
       def move(dx: Int, dy: Int):Unit = {
          x = x + dx
          y = y + dy
          println ("Point x location : " + x);
          println ("Point y location : " + y);
       }
    }
    
    object Demo {
       def main(args: Array[String]):Unit = {
          val pt = new Point(10, 20);
    
          // Move to a new location
          pt.move(10, 10);
       }
    }
    
    尝试一下
    输出:
    
    Point x location : 20
    Point y location : 30
    
  • 扩展类

    您可以扩展Scala基类,也可以像在Java中一样设计继承类(使用extends关键字),但是有两个限制:方法重写需要override关键字,并且只有主构造函数可以通过基本构造函数的参数。让我们扩展上面的类并添加另一个类方法。
    让我们以两个类的示例为例,Point类(与上面的示例相同)和Location类是使用extends关键字继承的类。这样的'extends '子句有两个作用:使Location类继承Point类的所有非私有成员,并且使Location类型成为Point类的子类型。因此,这里的Point类称为超类,Location类称为子类。扩展一个类并继承父类的所有功能称为继承,但是Scala仅允许从一个类继承。
    注意 -Point类中的move()方法和Location类中的move()方法不会覆盖相应的move定义,因为它们是不同的定义(例如,前者带有两个参数,而后者则带有三个参数)。
    尝试使用以下示例程序来实现继承。
    
    import java.io._
    
    class Point(val xc: Int, val yc: Int) {
       var x: Int = xc
       var y: Int = yc
       
       def move(dx: Int, dy: Int):Unit = {
          x = x + dx
          y = y + dy
          println ("Point x location : " + x);
          println ("Point y location : " + y);
       }
    }
    
    class Location(override val xc: Int, override val yc: Int,
       val zc :Int) extends Point(xc, yc){
       var z: Int = zc
    
       def move(dx: Int, dy: Int, dz: Int):Unit ={
          x = x + dx
          y = y + dy
          z = z + dz
          println ("Point x location : " + x);
          println ("Point y location : " + y);
          println ("Point z location : " + z);
       }
    }
    
    object Demo {
       def main(args: Array[String]):Unit = {
          val loc = new Location(10, 20, 15);
    
          // Move to a new location
          loc.move(10, 10, 5);
       }
    }
    
    尝试一下
    输出:
    
    Point x location : 20
    Point y location : 30
    Point z location : 20
    
  • 隐式类

    当类在作用域内时,隐式类允许与类的主构造函数进行隐式对话。隐式类是标有“implicit”关键字的类。Scala 2.10中引入了此功能。
    语法 -以下是隐式类的语法。在这里,隐式类始终在对象范围内,在该对象范围中,所有方法定义都可以使用,因为隐式类不能是顶级类。
    
    object <object name> {
       implicit class <class name>(<Variable>: Data type) {
          def <method>(): Unit =
       }
    }
    
    让我们以一个名为time()的隐式类IntTimes为例。这意味着times()包含一个循环事务,该事务将以给定的次数执行给定的语句。让我们假设给定的语句是“4 times println(“H​​ello”)”,这意味着println(“H​​ello”)语句将执行4次。以下是给定示例的程序。在此示例中,使用了两个对象类(运行和演示),因此我们必须将这两个类以各自的名称保存在不同的文件中,如下所示。Run.scala-将以下程序保存在Run.scala中。
    
    object Run {
       implicit class IntTimes(x: Int) {
          def times [A](f: =>A): Unit = {
             def loop(current: Int): Unit =
             
             if(current > 0){
                f
                loop(current - 1)
             }
             loop(x)
          }
       }
    }
    
    Demo.scala-将以下程序保存在Demo.scala中。
    
    import Run._
    
    object Demo {
       def main(args: Array[String]):Unit= {
          4 times println("hello")
       }
    }
    
    以下命令用于编译和执行这两个程序。
    
    \>scalac Run.scala
    \>scalac Demo.scala
    \>scala Demo
    
    输出:
    
    Hello
    Hello
    Hello
    Hello
    
    注意 -
    • 隐式类必须在另一个类/对象/特征内定义(不在顶层)。
    • 隐式类只能在其构造函数中使用一个非隐式参数。
    • 隐式类不能是范围与隐式类同名的任何方法,成员或对象。
  • 单例对象

    Scala比Java更面向对象,因为在Scala中,我们不能有静态成员。相反,Scala具有单例对象。单例是只能有一个实例(即对象)的类。您使用关键字对象而不是类关键字创建单例。由于无法实例化单例对象,因此无法将参数传递给主构造函数。您已经看到了使用单例对象的所有示例,在其中调用了Scala的main方法。以下是用于实现单例的相同示例程序。
    
    import java.io._
    
    class Point(val xc: Int, val yc: Int) {
       var x: Int = xc
       var y: Int = yc
       
       def move(dx: Int, dy: Int):Unit = {
          x = x + dx
          y = y + dy
       }
    }
    
    object Demo {
       def main(args: Array[String]):Unit= {
          val point = new Point(10, 20)
          printPoint
    
          def printPoint:Unit={
             println ("Point x location : " + point.x);
             println ("Point y location : " + point.y);
          }
       }
    }
    
    尝试一下
    编译并执行上述代码后,将产生以下结果-
    
    Point x location : 10
    Point y location : 20