zoukankan      html  css  js  c++  java
  • Spark记录-Scala类和对象

    本章将介绍如何在Scala编程中使用类和对象。类是对象的蓝图(或叫模板)。定义一个类后,可以使用关键字new来创建一个类的对象。 通过对象可以使用定义的类的所有功能。

    下面的图通过一个包含成员变量(name 和 rollNo)和成员方法(setName()setRollNo())的Student类的例子来演示类和对象。最后都是类的成员。类是一个模板的东西,而对象是真实存在的。 在下图中,Student是一个类,而具体学生:HariniJohn, 和 Maria 是学生类的对象,这此对象有是名字和注册号。

    类基础

    以下是在Scala中定义类的简单语法。这个类定义了两个变量xy以及一个move方法,它没有返回值。

    使用类的名称作为一个类构造函数,构造函数可以使用多个参数。 上面的代码定义了两个构造函数参数xcyc; 它们在类的整个定义中都是可见的。

    语法

    class Point(xc: Int, yc: Int) {
       var x: Int = xc
       var y: Int = yc
    
       def move(dx: Int, dy: Int) {
          x = x + dx
          y = y + dy
          println ("Point x location : " + x);
          println ("Point y location : " + y);
       }
    }
    
    Scala

    如本章前面所述,您可以使用关键字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) {
          x = x + dx
          y = y + dy
          println ("Point x location : " + x);
          println ("Point y location : " + y);
       }
    }
    
    object Demo {
       def main(args: Array[String]) {
          val pt = new Point(10, 20);
    
          // Move to a new location
          pt.move(10, 10);
       }
    }
    
    Scala

    将上述程序保存在Demo.scala中,并使用以下命令编译和执行此程序。

    D:softwarescala-2.12.3in>scalac Demo.scala
    
    D:softwarescala-2.12.3in>scala Demo
    Point x location : 20
    Point y location : 30
    
    D:softwarescala-2.12.3in>
    
    Shell

    扩展类

    在Scala中,我们可以扩展一个Scala类,使用与Java中相同的方式设计继承的类(使用extends关键字),但有两个限制:方法重写需要override关键字,只有主构造函数可以通过参数调用基类构造函数。让我们扩展上面的类,并增加一个类的方法。

    例子

    让我们使用两个类Point作为一个例子(与上面一样)和Location类,Location类是一个使用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) {
          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) {
          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]) {
          val loc = new Location(10, 20, 15);
    
          // Move to a new location
          loc.move(10, 10, 5);
       }
    }
    
    Scala

    将上述程序保存在源文件:Demo.scala中,并使用以下命令编译和执行此程序,输出结果如下 -

    D:softwarescala-2.12.3in>scalac Demo.scala
    
    D:softwarescala-2.12.3in>scala Demo
    Point x location : 20
    Point y location : 30
    Point z location : 20
    
    D:softwarescala-2.12.3in>
    
    Shell

    隐性类

    当类在范围内时,隐式类允许与类的主构造函数进行隐式对话。隐式类是一个标有'implicit'关键字的类。此功能在Scala 2.10中引入。

    语法 - 以下是隐式类的语法。这里,隐式类始终位于对象范围内,所有方法定义都被允许,因为隐式类不能是顶级类。

    语法

    object <object name> {
       implicit class <class name>(<Variable>: Data type) {
          def <method>(): Unit =
       }
    }
    
    Scala

    例子

    下面演示如何使用隐式类,创建一个名称为IntTimes的隐式类,并定义一个times()方法。times()包含一个循环事务,它将按给定的次数执行语句。假设要执行4println(“”Hello“)语句。

    以下是示例程序代码。在这个例子中,使用了两个对象类(Run 和 Demo),将这两个类保存在不同的文件中,名称如下 -

    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)
          }
       }
    }
    
    Scala

    Demo.scala - 将以下程序保存在源文件:Demo.scala 中 -

    import Run._
    
    object Demo {
       def main(args: Array[String]) {
          4 times println("hello")
       }
    }
    
    Scala

    用于以下命令编译和执行这两个程序,输出结果如下 -

    D:softwarescala-2.12.3in>scalac Demo.scala
    
    D:softwarescala-2.12.3in>scala Demo
    hello
    hello
    hello
    hello
    
    D:softwarescala-2.12.3in>
    
    Shell

    注 -

    • 隐式类必须在另一个类/对象/特征中定义(不在顶层)。
    • 隐式类在其构造函数中只能使用一个非默认参数。
    • 隐式类作用域中不可以具有与隐式类相同名称的的任何方法,成员或对象。

    单例对象

    Scala比Java更面向对象,因为在Scala中不能拥有静态成员,Scala它使用单例对象。单例是一种只能有一个实例的对象。使用object关键字对象而不是类关键字创建单例。由于无法实例化单例对象,因此无法将参数传递给主构造函数。下面列出Scala使用单例对象的所有示例。

    以下是实现单例的示例程序 -

    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) {
          x = x + dx
          y = y + dy
       }
    }
    
    object Demo {
       def main(args: Array[String]) {
          val point = new Point(10, 20)
          printPoint
    
          def printPoint{
             println ("Point x location : " + point.x);
             println ("Point y location : " + point.y);
          }
       }
    }
    
    Scala

    将上述程序保存在源文件:Demo.scala 中,使用以下命令编译和执行此程序,输出结果如下 -

    D:softwarescala-2.12.3in>scalac Demo.scala
    
    D:softwarescala-2.12.3in>scala Demo
    Point x location : 10
    Point y location : 20
    
    Shell

    Scala单例和伴生对象

    单例(Singleton)对象是一个通过使用object关键字而不是使用class关键字声明的对象。其它对象不需要调用在单例对象中声明的方法。

    在scala中,没有静态的概念。 所以scala创建一个单例对象来为程序的执行提供入口点。
    如果不创建单例对象,代码也会成功编译,但不会产生任何输出。单例对象中声明的方法可以全局访问。单例对象可以扩展类和性状。

    Scala单例对象示例

    object Singleton{  
        def main(args:Array[String]){  
            SingletonObject.hello()         // No need to create object.  
        }  
    }  
    
    
    object SingletonObject{  
        def hello(){  
            println("Hello, This is Singleton Object")  
        }  
    }
    
    Scala

    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -

    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    Hello, This is Singleton Object
    
    Shell

    Scala伴生对象

    在scala中,当有一个与单例(singleton)对象同名的类时,它被称为伴生(companion)类,单例(singleton)对象调用伴生对象。

    伴生类及其伴随对象必须在同一个源文件中定义。

    Scala伴生对象示例

    class ComapanionClass{  
        def hello(){  
            println("Hello, this is Companion Class.")  
        }  
    }  
    object Demo{  
        def main(args:Array[String]){  
            new ComapanionClass().hello()  
            println("And this is Companion Object.")  
        }  
    }
    
    Scala

    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -

    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    Hello, this is Companion Class.
    And this is Companion Object.

    Scala Case类和对象

    Scala Case类只是常规类,默认情况下是不可变的,可通过模式匹配可分解。它使用相等(equal)方法在结构上比较实例。它不使用new关键字实例化对象。默认情况下,case类中列出的所有参数默认使用publicimmutable修辞符。语法
    case class className(parameters)
    
    Scala
    Scala Case类示例
    case class CaseClass(a:Int, b:Int)  
    
    object Demo{  
        def main(args:Array[String]){  
            var c =  CaseClass(10,10)       // Creating object of case class  
            println("a = "+c.a)               // Accessing elements of case class  
            println("b = "+c.b)  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    a = 10
    b = 10
    
    Shell
    Case类支持模式匹配。 所以,可以在模式中使用它。以下是Case类和模式的示例。

    Scala Case类和模式匹配示例

    没有参数的case类将被声明为case对象而不是case类。 默认情况下,case对象是可序列化的。
    trait SuperTrait  
    case class CaseClass1(a:Int,b:Int) extends SuperTrait  
    case class CaseClass2(a:Int) extends SuperTrait         // Case class  
    case object CaseObject extends SuperTrait               // Case object  
    object Demo{  
        def main(args:Array[String]){  
            callCase(CaseClass1(10,10))  
            callCase(CaseClass2(10))  
            callCase(CaseObject)  
        }  
        def callCase(f:SuperTrait) = f match{  
            case CaseClass1(f,g)=>println("a = "+f+" b ="+g)  
            case CaseClass2(f)=>println("a = "+f)  
            case CaseObject=>println("No Argument")  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    a = 10 b =10
    a = 10
    No Argument
    
    Shell

    Scala构造函数

    在scala中,构造函数不是特殊的方法。Scala提供主要和任意数量的辅助构造函数。我们将在下面的例子中逐一个详细解释。

    Scala默认主构造函数

    在scala中,如果不指定主构造函数,编译器将创建一个主构造函数的构造函数。 所有类的主体的声明都被视为构造函数的一部分。它也被称为默认构造函数。Scala默认主构造函数示例
    class Student{  
        println("Hello from default constructor");  
    }
    
    Scala

    Scala主要构造函数

    Scala提供了一个类的主构造函数的概念。如果代码只有一个构造函数,则可以不需要定义明确的构造函数。它有助于优化代码,可以创建具有零个或多个参数的主构造函数。Scala主构造函数示例
    class Student(id:Int, name:String){  
        def showDetails(){  
            println(id+" "+name);  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var s = new Student(1010,"Maxsu");  
            s.showDetails()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    1010 Maxsu
    
    Shell

    Scala次要(辅助)构造器

    可以在类中创建任意数量的辅助构造函数,必须要从辅助构造函数内部调用主构造函数。this关键字用于从其他构造函数调用构造函数。当调用其他构造函数时,要将其放在构造函数中的第一行。Scala二次构造函数示例
    class Student(id:Int, name:String){  
        var age:Int = 0  
        def showDetails(){  
            println(id+" "+name+" "+age)  
        }  
        def this(id:Int, name:String,age:Int){  
            this(id,name)       // Calling primary constructor, and it is first line  
            this.age = age  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var s = new Student(1010,"Maxsu", 25);  
            s.showDetails()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    1010 Maxsu 25
    
    Shell

    Scala示例:构造器重载

    在scala中,可以重载构造函数。下面我们来看一个例子。
    class Student(id:Int){  
        def this(id:Int, name:String)={  
            this(id)  
            println(id+" "+name)  
        }  
        println(id)  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            new Student(101)  
            new Student(100,"Minsu")  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    101
    100
    100 Minsu

    Scala方法重载

    Scala提供了方法重载功能,使我们能够定义相同名称但使用不同参数或数据类型的方法。 它有助于优化代码。Scala方法通过使用不同的参数重载示例在下面的例子中,定义了两个具有不同数量的参数但具有相同数据类型的add方法。
    class Arithmetic{  
        def add(a:Int, b:Int){  
            var sum = a+b  
            println(sum)  
        }  
        def add(a:Int, b:Int, c:Int){  
            var sum = a+b+c  
            println(sum)  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var a  = new Arithmetic();  
            a.add(10,20);  
            a.add(10,20,30);  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    30
    60
    
    Shell
    Scala通过使用不同的数据类型方法重载示例在下面的例子中,创建了一个使用两个相同数量的参数但是不同的数据类型的add方法。
    class Arithmetic{  
        def add(a:Int, b:Int){  
            var sum = a+b  
            println(sum)  
        }  
        def add(a:Double, b:Double){  
            var sum = a+b  
            println(sum)  
        }  
    }  
    object Demo{  
        def main(args:Array[String]){  
            var b = new Arithmetic()  
            b.add(10,20)  
            b.add(10.0,20.1)  
    
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    30
    30.1

    Scala this关键字

    在scala中,this是一个关键字,用于引用当前对象。可以使用this关键字调用实例变量,方法,构造函数。

    Scala this示例

    在以下示例中,这用于调用实例变量和主要构造方法。
    class ThisExample{  
        var id:Int = 0  
        var name: String = ""  
        def this(id:Int, name:String){  
            this()  
            this.id = id  
            this.name = name  
        }  
        def show(){  
            println(id+" "+name)  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var t = new ThisExample(1010,"Maxsu")  
            t.show()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    1010 Maxsu
    
    Shell
    Scala构造函数使用this关键字调用在下面的例子中,使用this关键字来调用构造函数。它演示了如何从其他构造函数调用构造函数。必须确保this必须放在构造函数中的第一个语句,同时调用其他构造函数,否则编译器会抛出错误。
    class Student(name:String){  
        def this(name:String, age:Int){  
            this(name)  
            println(name+" "+age)  
        }      
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var s = new Student("Maxsu",1000)  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    Maxsu 1010

    Scala继承

    继承是面向对象的概念,用于代码的可重用性。可以通过使用extends关键字来实现继承。 为了实现继承,一个类必须扩展到其他类,被扩展类称为超类或父类。扩展的类称为派生类或子类。示例
    class SubClassName extends SuperClassName(){  
        /* Write your code  
         *  methods and fields etc. 
         */  
     }
    
    Scala

    继承的简单例子

    Scala单继承示例
    class Employee{  
        var salary:Float = 11100  
    }  
    
    class Programmer extends Employee{  
        var bonus:Int = 5100  
        println("Salary = "+salary)  
        println("Bonus = "+bonus)  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            new Programmer()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    Salary = 11100.0
    Bonus = 5100
    
    Shell

    Scala继承类型

    Scala支持各种类型的继承,包括单一,多层次,多重和混合。可以在类中使用单一,多层次和层次结构。多重和混合只能通过使用特征来实现。在这里,通过使用图形表示所有类型的继承。
    class A{  
        var salary1 = 10000  
    }  
    
    class B extends A{  
        var salary2 = 20000  
    }  
    
    class C extends B{  
        def show(){  
            println("salary1 = "+salary1)  
            println("salary2 = "+salary2)  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){
            var c = new C()  
            c.show()  
    
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    salary1 = 10000
    salary2 = 20000
    
    Shell

    Scala方法覆盖

    继承是面向对象的概念,用于代码的可重用性。可以通过使用extends关键字来实现继承。 为了实现继承,一个类必须扩展到其他类,被扩展类称为超类或父类。扩展的类称为派生类或子类。示例
    class SubClassName extends SuperClassName(){  
        /* Write your code  
         *  methods and fields etc. 
         */  
     }
    
    Scala

    继承的简单例子

    Scala单继承示例
    class Employee{  
        var salary:Float = 11100  
    }  
    
    class Programmer extends Employee{  
        var bonus:Int = 5100  
        println("Salary = "+salary)  
        println("Bonus = "+bonus)  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            new Programmer()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    Salary = 11100.0
    Bonus = 5100
    
    Shell

    Scala继承类型

    Scala支持各种类型的继承,包括单一,多层次,多重和混合。可以在类中使用单一,多层次和层次结构。多重和混合只能通过使用特征来实现。在这里,通过使用图形表示所有类型的继承。
    class A{  
        var salary1 = 10000  
    }  
    
    class B extends A{  
        var salary2 = 20000  
    }  
    
    class C extends B{  
        def show(){  
            println("salary1 = "+salary1)  
            println("salary2 = "+salary2)  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){
            var c = new C()  
            c.show()  
    
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    D:softwarescala-2.12.3in>scala Demo
    salary1 = 10000
    salary2 = 20000

    Scala final关键字

    final是一个关键字,用于防止超类成员继承为派生类。也可以声明final变量,方法和类。

    Scala final变量示例

    不能覆盖子类中的final变量,我们来看下面一个例子。Scala单继承示例
    class Vehicle{  
         final val speed:Int = 60  
    }  
    class Bike extends Vehicle{  
       override val speed:Int = 100  
        def show(){  
            println(speed)  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var b = new Bike()  
            b.show()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    Demo.scala:5: error: overriding value speed in class Vehicle of type Int;
     value speed cannot override final member
       override val speed:Int = 100
                    ^
    one error found
    
    Shell

    Scala final方法

    在父类中的final方法声明不能被覆盖。 如果不想让它被覆盖,则可以把方法定义成为final。尝试覆盖final方法将导致编译时错误。Scala final方法示例
    class Vehicle{  
         final def show(){  
             println("vehicle is running")  
         }  
    }  
    class Bike extends Vehicle{  
       //override val speed:Int = 100  
        override def show(){  
            println("bike is running")  
        }  
    }  
    object Demo{  
        def main(args:Array[String]){  
            var b = new Bike()  
            b.show()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    Demo.scala:8: error: overriding method show in class Vehicle of type ()Unit;
     method show cannot override final member
        override def show(){
                     ^
    one error found
    
    Shell
    Scala final类示例也可以定义final类,final类不能继承。 如果定义了一个类为final类,那就不能进一步扩展了。
    final class Vehicle{  
         def show(){  
             println("vehicle is running")  
         }  
    
    }  
    
    class Bike extends Vehicle{  
           override def show(){  
            println("bike is running")  
        }  
    }  
    
    object Demo{  
        def main(args:Array[String]){  
            var b = new Bike()  
            b.show()  
        }  
    }
    
    Scala
    将上面代码保存到源文件:Demo.scala中,使用以下命令编译并执行代码 -
    D:softwarescala-2.12.3in>scalac Demo.scala
    Demo.scala:8: error: illegal inheritance from final class Vehicle
    class Bike extends Vehicle{
                       ^
    one error found
     
  • 相关阅读:
    包路径与沙盒路径
    iOS 文件操作:沙盒(SandBox)、文件操作(FileManager)、程序包(NSBundle)
    从Swift桥接文件到Clang-LLVM
    人生•修养:知行合一
    First-class citizen
    阿里云部署SSL证书详解
    YourPHP笔记
    ThinkPHP函数详解:L方法
    robots书写说明:
    如何设置让网站禁止被爬虫收录?robots.txt
  • 原文地址:https://www.cnblogs.com/xinfang520/p/7728835.html
Copyright © 2011-2022 走看看