Scala language foundation: classes and objects in object-oriented programming

Scala is an object-oriented language like Java and Python. This article explains the concepts and examples of classes and objects in scala object-oriented.

1. class

Classes and objects are the basic concepts of object-oriented programming such as Java and C++. A class is a blueprint for creating objects. After defining a class, you can use the new keyword to create objects.

simple instance of the class

The simplest form of class definition is:

class Counter{
     //这里定义类的字段和方法
}

Then, you can use the new keyword to generate objects:

new Counter //或者new Counter()

properties and methods

Let's add properties and methods to this class:

class Counter {
    private var value = 0
    def increment(): Unit = { value += 1}
    def current(): Int = {value}
}

In the above definition, we set the value field as private, so that it becomes a private field, which cannot be accessed by the outside world, and can only be accessed within the class. If there are no modifiers in front of the field, it will be public by default, and the field can be accessed externally. For the class, we don't need to declare it as public, and the multiple classes contained in the Scala file are all visible to each other.

For the definition of the method, it is realized through def. The above increment() is a method with no parameters. The Unit after the colon is the type of the return value. If Scala does not return any value, it is represented by Unit, which is equivalent to the void type in Java. The return value of the method does not need to rely on the return statement. The value of the last expression in the method is the return value of the method. For example, there is only one statement "value" in the current() method above, then the value of value is the value of the method return value.

create object

Next we create a new object and call its methods:

val myCounter = new Counter
myCounter.increment() //或者也可以不用圆括号,写成myCounter.increment
println(myCounter.current)

As can be seen from the above code, Scala can omit the parentheses after the method name when calling a parameterless method.

compile and execute

Now, let's take the complete code above and execute it on the Linux system. After logging in to the Linux system, open the command line terminal (you can use the shortcut key combination Ctr+Alt+T to quickly open the command line terminal), enter the "/usr/local/scala/mycode" directory, and then use the vim editor Create a new TestCounter.scala code file, as follows:

cd /usr/local/scala/mycode
vim TestCounter.scala

Enter the following code in TestCounter.scala:

class Counter {
    private var value = 0
    def increment(): Unit = { value += 1}
    def current(): Int = {value}
}
val myCounter = new Counter
myCounter.increment()
println(myCounter.current)

Exit the vim editor after saving. Then, use the scala command to execute this code file:

scala TestCounter.scala

getter & setter

Let's take a look at how to set and read values ​​for fields in a class. As we know, in Java, this is achieved through getter and setter methods. In Scala, the implementation of getter and setter methods is also provided, but they are not defined as getXxx and setXxx.

We continue to modify the TestCounterJVM.scala file:

class Counter {
    var value = 0 //注意这里没有private修饰符,从而让这个变量对外部可见
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter = new Counter
        println(myCounter.value)  //不是用getXxx获取字段的值
        myCounter.value = 3 //不是用setXxx设置字段的值
        myCounter.increment(1) //这里设置步长为1,每次增加1
        println(myCounter.current)
    }
}

Now we use the scalac command to compile the above code, and an error will be reported, because the modifier private is used in front of the value field, which has become a private field and cannot be accessed externally.
Then, after value becomes a private field, Scala does not provide getter and setter methods, how can you access the value field? The solution is that, in Scala, you can define getter-like and setter-like methods called value and value_= respectively, as follows:

class Counter {
    private var privateValue = 0  //变成私有字段,并且修改字段名称
    def value = privateValue //定义一个方法,方法的名称就是原来我们想要的字段的名称
    def value_=(newValue: Int){
        if (newValue > 0) privateValue = newValue //只有提供的新值是正数,才允许修改
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter = new Counter
        println(myCounter.value)  //打印value的初始值
        myCounter.value = 3 //为value设置新的值
        println(myCounter.value)  //打印value的新值 
        myCounter.increment(1) //这里设置步长为1,每次增加1
        println(myCounter.current)
    }
}

Compile and execute this file, and you can get three lines of execution results, the first line is 0, the second line is 3, and the third line is 4.

auxiliary constructor

A Scala constructor consists of a primary constructor and several (zero or more) auxiliary constructors.
Let's first get acquainted with the auxiliary constructor. The name of the auxiliary constructor is this, and each auxiliary constructor must call a previously defined auxiliary constructor or primary constructor.
Let's define a class with an auxiliary constructor, and we modify the Counter class definition above:

class Counter {
    private var value = 0 //value用来存储计数器的起始值
    private var name = "" //表示计数器的名称
    private var mode = 1 //mode用来表示计数器类型(比如,1表示步数计数器,2表示时间计数器)
    def this(name: String){ //第一个辅助构造器
        this() //调用主构造器
        this.name = name
    }
    def this (name: String, mode: Int){ //第二个辅助构造器
        this(name) //调用前一个辅助构造器
        this.mode = mode
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter1 = new Counter  //主构造器
        val myCounter2 = new Counter("Runner") //第一个辅助构造器,计数器的名称设置为Runner,用来计算跑步步数
        val myCounter3 = new Counter("Timer",2) //第二个辅助构造器,计数器的名称设置为Timer,用来计算秒数
        myCounter1.info  //显示计数器信息
        myCounter1.increment(1)     //设置步长  
        printf("Current Value is: %d\n",myCounter1.current) //显示计数器当前值
        myCounter2.info  //显示计数器信息
        myCounter2.increment(2)     //设置步长  
        printf("Current Value is: %d\n",myCounter2.current) //显示计数器当前值
        myCounter3.info  //显示计数器信息
        myCounter3.increment(3)     //设置步长  
        printf("Current Value is: %d\n",myCounter3.current) //显示计数器当前值

    }
}

After compiling and executing the above code, the following results are obtained:

Name: and mode is 1
Current Value is: 1
Name:Runner and mode is 1
Current Value is: 2
Name:Timer and mode is 2
Current Value is: 3

primary constructor

Every class in Scala has a primary constructor. However, Scala's primary constructor is significantly different from Java. Scala's primary constructor is the entire class body, and all parameters required by the constructor need to be listed after the class name. These parameters are compiled into fields, and the value of the field It is the value of the parameter passed in when creating the object.
For the above example of setting name and mode for the counter, just now we used the auxiliary constructor to set the value of name and mode, now we do it again, this time we use the main constructor to set the value of name and mode .

class Counter(val name: String, val mode: Int) {
    private var value = 0 //value用来存储计数器的起始值    
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}
object MyCounter{
    def main(args:Array[String]){       
        val myCounter = new Counter("Timer",2)
        myCounter.info  //显示计数器信息
        myCounter.increment(1)  //设置步长  
        printf("Current Value is: %d\n",myCounter.current) //显示计数器当前值       
    }
}

After compiling and executing the above code, the following results are obtained:

Name:Timer and mode is 2
Current Value is: 1

2. Object

singleton object

Scala does not provide static methods or static fields like Java, but you can use the object keyword to implement singleton objects, which have the same functions as Java static methods.

object Person {
    private var lastId = 0  //一个人的身份编号
    def newPersonId() = {
        lastId +=1
        lastId
    }
}

As can be seen from the above definition, the definition of a singleton object is very similar to the definition of a class. The obvious difference is that the keyword object is used instead of the keyword class.
Assuming there is a class management system, whenever a new class member arrives, an identity number is assigned to it. When the first person joins the class, you can call Person.newPersonId() to get the ID.

companion object

In Java, we often need to use classes that contain both instance methods and static methods. In Scala, this can be achieved through companion objects. When a singleton object has the same name as a class, it is called a "companion object" of that class. A class and its companion object must exist in the same file and have mutual access to private members (fields and methods).

The following demonstrates how to use the companion object through an example. In the "/usr/local/scala/mycode" directory, use the vim editor to recreate a test.scala, and enter the following code in the file:

class Person {
    private val id = Person.newPersonId() //调用了伴生对象中的方法
    private var name = ""
    def this(name: String) {
        this()
        this.name = name
    }
    def info() { printf("The id of %s is %d.\n",name,id)}
}
object Person {
    private var lastId = 0  //一个人的身份编号
    private def newPersonId() = {
        lastId +=1
        lastId
    }
    def main(args: Array[String]){
        val person1 = new Person("xiaoming")
        val person2 = new Person("xiaohong")
        person1.info()
        person2.info()      
    }
}

The newPersonId() defined in the companion object actually implements the function of the static method in Java. Therefore, the value returned by calling newPersonId() of the instantiated object person1 is 1, and the value returned by calling newPersonId() of the instantiated object person2 is 2. As we said, the Scala source code will become JVM bytecode after compilation. In fact, after compiling the above source code file, the class and object in Scala will be combined into one at the Java level, and the members in the class Became an instance member, and an object member became a static member.

application object

Every Scala application must start with an object's main method. The HelloWorld program we introduced earlier is a very typical example.
We can recreate a test.scala with the vim editor in the "/usr/local/scala/mycode" directory, and enter the following code in the file:

object HelloWorld {
    def main(args: Array[String]){
        println("Hello, World!")
    }
}

In order to run the above code, we can now use two different methods.
The first method: directly use the scala command to run to get the result.
Because there is no class defined in this code, it is a singleton object. Therefore, you can directly use the scala command to run to get the result without compiling. The command is as follows:

cd /usr/local/scala/mycode
scala test.scala

apply & update

We often use the apply method and the update method of the object. Although we don’t notice it on the surface, in fact, in Scala, the apply method and the update method will be called according to the relevant conventions. The convention is as follows: use parentheses to pass to When assigning one or more parameters to a variable (object), Scala will convert it into a call to the apply method; similarly, when assigning an object with parentheses and including one or several parameters, the compiler will call the object The update method, when called, uses the parameters in the brackets and the object on the right of the equal sign together as the input parameters of the update method to execute the call.

Next we test whether the apply method is called. You can enter the following code in the "/usr/local/scala/mycode/test.scala" file of the Linux system:

class TestApplyClass {
    def apply(param: String): String = {
        println("apply method called, parameter is: " + param)
        "Hello World!"
    }
}
val myObject = new TestApplyClass
println(myObject("param1"))

After running, you will get the following results:

apply method is called, parameter is:param1
Hello World!

If the statement println(myObject("param1")) is commented out, the above result will not appear. It can be seen that the apply method is indeed called, and it is called when myObject("param1") is executed. After the call, "Hello World!" will be used as the return value, so "Hello World" will be printed.

The apply method was introduced earlier. In fact, the update method is similar (interested readers can find online information to learn how to test the update method, so I won’t go into details here), for example:

val myStrArr = new Array[String](3) //声明一个长度为3的字符串数组,每个数组元素初始化为null
myStrArr(0) = "BigData" //实际上,调用了伴生类Array中的update方法,执行myStrArr.update(0,"BigData")
myStrArr(1) = "Hadoop" //实际上,调用了伴生类Array中的update方法,执行myStrArr.update(1,"Hadoop")
myStrArr(2) = "Spark" //实际上,调用了伴生类Array中的update方法,执行myStrArr.update(2,"Spark")

It can be seen from the above that when performing tuple assignment, the reason why the square brackets myStrArr[0] in Java is not used, but the form of parentheses, myStrArr(0), is used because of the above-mentioned update method mechanism .

Reference link:

http://dblab.xmu.edu.cn/blog/spark/

https://www.runoob.com/scala/scala-tutorial.html

History recommendation

Mom no longer has to worry about dual system installation!

Spark Machine Learning: Model Evaluation Metrics

Spark Machine Learning: Frequent Pattern Mining

Reptile combat: Selenium crawls Jingdong products

Reptile combat: Douban movie top250 crawling

Reptile combat: Scrapy framework crawls QQ music

Data Analysis and Mining

Data Structures and Algorithms

Machine Learning and Big Data Components

Welcome to pay attention, thank you for "watching", it's rare to follow the fate~

 

Guess you like

Origin blog.csdn.net/qq_36936730/article/details/106132543