The Scala language is derived from Java, so it is by nature an object-oriented language. This chapter shows you how to use constructors in Scala to construct a class object, along with a brief introduction to the exception mechanism in Scala.

Define a class using the class keyword

Let’s go straight to a simple Cat template:

class Cat{
  var name : String = "null"
  var age : Int = _
  var color : String = _
  override def toString = s"Cat($name.$age.$color)"
}
Copy the code

Defining a class in Scala still uses the class keyword. (So far we have used the object modifier, and we will refer to the difference between class and object later.)

In general, attributes inside a class use the VAR keyword (because you can modify these variables externally). In Scala, variable declarations are always assigned. However, default values can be assigned to this attribute using the _ notation, such as 0 for members of type AnyVal and Null for members of type AnyRef.

At the Scala level, members defined internally by Cat are public, albeit without any modifiers. But if we look at the compiled cat.class file, these properties are actually modified to be private, except that the compiler generates the public name(equivalent to Java’s get method) and name_$eq methods in addition. (Equivalent to Java’s set method)

These details are transparent at the Scala level, so we have unrestricted access to a Scala class member unless that member is explicitly labeled as a private keyword.

In Scala, access to class members is simplified: they are either public with no modifiers, or private or protected with modifiers or subclass access only. That is, class members in Scala have only three types of permissions.

class Cat {
  / / public
  val age : Int = 1
  // Allow subclass access
  protected val toy : String = "toy"
  // Private member
  private val name : String = "kitty"
}
Copy the code

@ BeanProperty annotations

To match Java usage, Scala provides the @beanProperty annotation to provide the set/ GET method for an attribute.

@BeanProperty
var name : String = _
Copy the code

Is equivalent to:

def setName(inName : String) :Unit= {this.name = inName
}

def getName : String = this.name
Copy the code

Note that to use this annotation, the internal member needs to be mutable var. And cannot be decorated with the private keyword.

Some details in the Scala file

Unlike Java, a scala source file can have multiple exposed classes inside it. At compile time, Scalac will encode different classes in a. Scala file into separate. Class files.

One other detail we can see during compilation is that if class is declared, only one.class file will be compiled. If object is declared, two.class files are generated simultaneously. We’ll talk about it in more detail in subsequent companion objects.

Assign “_” and null

Note that both types of assignment require the variable to display the declared data type.

Assigning a value of “_” assigns a default value to the current variable. If the member does not explicitly declare the data type, an error will be reported at program execution:

Unbound placeholder parameter, which means no binding parameter value type.

For different data types, the default values for _ are shown in the following table.

type The value of the corresponding
Byte Short Int Long 0
Float Double 0.0
StringAnyRef Null
Boolean false

If null is assigned, the default is for this attribute to point to an empty reference. If null is assigned and the declared data type is not displayed, the property becomes null (note! In Scala, NULL is a single type, just like Unit. This attribute cannot be assigned any value other than null, which can also cause problems when used.

Scala can automatically infer from the Type of the new object when declaring object variables, so in general: Type can be omitted. But if we want to define an upper transition, we need to explicitly write the data type.

object CreateOBJ {
  def main(args: Array[String) :Unit = {
   	// Defines an upper transition object.
    val person : Person = new Emp
  }
  class Person {}
  class Emp extends Person{}}Copy the code

Class method

Scala’s approach is the same as the function definition approach in the previous chapter. According to my custom, functions declared inside a class are specifically referred to as methods. Methods declared inside a class-decorated class are instance methods.

  1. When Scala starts execution, it creates a main stack in the stack area, which is destroyed at the end of execution.

  2. When a Scala program executes to a method, a new stack is always opened.

  3. Each stack is an independent space, and data types of AnyVal type are independent and do not affect each other.

  4. When the method completes, the stack opened by the method is reclaimed by the JVM.

Scala constructor (constructor)

Scala’s constructors are quite different from Java’s.

The constructor is used to initialize a new object.

In Java, a class can define multiple different constructors, called constructor overloading. If no declaration constructor is shown, Java provides a no-parameter constructor by default. If the constructor is declared in the display, Java will no longer provide a no-parameter constructor. And the Java constructor omits super() in the first line;

Scala’s constructors include a primary constructor and a secondary constructor. The compiler takes different parameters to distinguish which constructor to choose. Whatever the constructor is, it does not need to return a value.

The main constructor

The main constructor is declared directly on the class, as shown in the following code block. The class name is followed directly by a parameter list to assign values to the internal members of the Teacher.

class Teacher(inAge: Int = 25, inName: String="Tom") {
  var age: Int = inAge
  var name: String = inName
}
Copy the code

This is equivalent to the Java way of declaring:

// The above constructor is written in Java:
public Teacher(int inAge,String inName){
	this.age = inAge;
	this.Name = inName;
}
Copy the code

The code block inside the class can actually be thought of as the body of a main constructor. When the main program uses the main constructor to create an instance of a class, it executes each statement inside the class as if it were a function, and the declarations inside the function become the attribute members and internal methods of the class.

// The above constructor is written in Java:
public Teacher(int inAge,String inName){
	this.age = inAge;
	this.Name = inName;
    // Our statements in Scala's class are written to the body of the constructor function.
	System.out.println("Hire a teacher.")}Copy the code

We even have a shorter version:

class Teacher(var inAge: Int = 25,var inName: String="Tom")
Copy the code

See the difference? It directly omits the step of assigning “external parameters to internal members”, which is equivalent to placing the internal members directly into the parameter list for initialization. (This ellipsis is limited to the primary constructor.)

In addition, in the singleton pattern, to hide the constructor of a class, the common practice in Java is to declare its constructor private. So how do you do this in Scala? We simply add the private keyword to the front of the argument list.

class Teacher private (var inAge: Int = 25,var inName: String="Tom")
Copy the code

Thus, we cannot directly call the Teacher constructor to create an instance. Inexplicably, however, IntelliJ IDEA does not report syntax errors, but does not tell you that you have permission to access such constructors until after compilation.

Auxiliary constructor

Use the this keyword to name the method inside the class to indicate that the method is a helper constructor. Attention! The first line in the secondary constructor must either display or implicitly call the primary constructor! (This feels like a Java class where the super constructor must be written on the first line of the child constructor.)

The fundamental reason for this is that only the primary constructor makes a connection to the parent class through the extends keyword. The secondary constructor of a subclass cannot directly call any of the constructors of the parent class, so the primary constructor must be called before the secondary constructor is called. This is like a decorator pattern: the primary constructor is called to construct its parent class and primary attributes, and then the secondary constructor is used to complement the other extended attributes.

Calling the primary constructor explicitly is easy to understand, but what is calling the primary constructor indirectly? That is, one helper constructor calls another helper constructor, which calls the primary constructor.

Let’s just give the following code:

class B{
  println("1")
  def this(int: Int) {//B calls B's primary constructor before calling the secondary constructor
    this
    println("2")}}// The primary constructor of A calls the secondary constructor of B
class A extends B(5){
  println("3")
  def this(string: String) {// The primary constructor of A is called before the secondary constructor of A is called
    this
    println("4")}}Copy the code

Here, the example of class A calls the parameterized constructor of parent class B before initialization.

So how many constructors does this line actually call?

// Use the auxiliary constructor of A to construct the object.
val a : A = new A("a")
Copy the code

As a result, four constructors were called. Because the program will print in the console: 1, 2, 3, 4. The program first calls the primary constructor of the parent class B, and then the secondary constructor of B. When THE B build is complete, A’s primary constructor is called, and then A’s secondary constructor is called.

Define exceptions in Scala

A quick review of Java exceptions: Java exceptions fall into two categories, runtimeExceptions and unchecked exceptions.

A. abnormalities, refer to the JVM at run time due to program logic problem could be caused by accidental: such as NullPointerException ArrayIndexOutOfBoundsException, etc.

A non-checked exception refers to a program problem that may be caused by an external factor: for example, ClassNotFoundException (the class that is being reflected does not actually exist in the project).

The exception mechanism in Scala, however, follows Java’s try-catch system, but is written differently and simplified in form: in Scala, only run-time exceptions are available. Here is an example:

try {
    
  val a: Int = 10 / 0
  println(a)
    
} catch {
  case ex: ArithmeticException => ex.printStackTrace()
  case ex: Exception => ex.printStackTrace()
}finally {

  println("Try-catch completed")}Copy the code

In Scala, you just need to write a catch: it will automatically pattern match the caught exception and execute the code block that follows =>. (Be careful not to write => as ->, as distinct from Java’s lambda syntax).

Java has a catch order requirement: small exceptions are written first. Extensive exceptions are written later. Scala doesn’t impose strict restrictions on this, but it’s still a programming habit to follow.

Scala can add an @throws annotation to def functions to indicate possible exceptions:

@throws(classOf[NumberFormatException])
def mis(stringInt:String) :Int= {
  stringInt.toInt
}
Copy the code

This blog post documents an overview of two Java exceptions.