Scala classes and singletons

Keywords: Java Scala

1. Basic operation of class

1.1. Definition of class

Class or type is the abstraction of an objective class of things. A class keyword is used to describe the properties, behaviors, etc. of this kind of things in this class.

In other words, a kind of things described in computer language, that is, classes, are identified by the keyword class in Java and scala.

Because a class is an abstraction of a class of things, it does not have the ability to perform specific actions. To complete specific operations, you need to use the instance or object of the class.

//Create a class in scala
object _01ClassOps {
	def main(args: Array[String]): Unit = {
		/*
			scala As like as two peas, the corresponding class objects are built in the same way as java, using the keyword new.
			And constructor to complete the creation of the instance
			scala You can use the default parameterless constructor to complete instance creation,
			At the same time, if a class has a parameterless constructor, it can be omitted () when creating objects
		 */
		val p = new Person()
//		val p1 = new Person

//		p.name =
		p.setName("Liu Jiahao")
		p.setAge(169)

		p.show()
	}
}


class Person {
	/*
		_The function of is equivalent to private String name in java;
		If you want to use, The previous member variable should specify the data type
	 */
	private var name:String = _

	private var age = 13
	def show(): Unit = {
		println(s"name=${name}\tage=${age}")
	}

	def setName(name:String):Unit = {
        //Use this keyword to distinguish between member variables and local variables after naming conflicts
		this.name = name
	}

	def getName() = this.name
	//Single-Row Functions 
//	def setAge(age:Int) = this.age = age
	def setAge(age:Int): Unit = {
		if(age < 0 || age > 150) {
			throw new RuntimeException("The earth doesn't welcome you~")
		}
		this.age = age
	}

	def getAge = this.age
}

1.1.1. getter/setter operation

In scala, the @ BeanProperty annotation is used to provide getter/setter for member variables, which cannot coexist with the private access modifier
This method defines operations similar to Java beans, which are rarely used in scala. What are the main functions of Java beans
To put it bluntly, data is transferred between business lines / layers. scala provides another result to simulate the bean - case class (sample class, sample class) in java

class Student {
	@BeanProperty var name:String = _

	private var age = 13
}

1.2. Structure of class

The constructor of a class. In java, the constructor (constructor) of a class can be divided into a constructor with parameters, a constructor without parameters, or a default constructor. The so-called default constructor means that the user does not specify / create the relevant constructor, but the virtual opportunity automatically adds a constructor without / empty parameters to our class for object creation.

In java, a class can have several constructors, either nonparametric constructors or parametric constructors. If the user provides constructors, there will be no default constructors at this time.

. 2.2. Constructors in Scala

There are two types of constructors in scala -- the main constructor and the auxiliary constructor.

Description of the constructor

object _02ConstructorOps {
	def main(args: Array[String]): Unit = {
		val p = new Person("Hua Yong", 23)
		p.show()
	}
}

class Person() {

	private var name:String = _

	private var age:Int = _

	def Person(): Unit = {
		println("--Person()--Is it the default constructor?")
	}

	//Custom constructor the first sentence of a custom constructor must call other constructors
	def this(name:String, age:Int) {
		this()
		this.name = name
		this.age = age
		println("---------this(name:String, age:Int)---------")
	}


	println("-------------constructor ~----------------")
	def show(): Unit = {
		println(s"name=${name}\tage=${age}")
	}
}

In this example, the default constructor intertwined with the class definition is the most important constructor in scala class - the main constructor (the default constructor is the parameterless main constructor, defined between the class name and the {of the class, omitting ()).

The other custom constructors, that is, the constructors defined in the class through def this(xxx), are called auxiliary constructors. At the same time, the first sentence of the auxiliary constructor must call the main constructor or other auxiliary constructors of this class through this.

object _02ConstructorOps {
	def main(args: Array[String]): Unit = {
		val _3p = new Person(77)
		_3p.show()
	}
}

class Person(var name:String, var age:Int) {

	def Person(): Unit = {
		println("--Person()--Is it the default constructor?")
	}

	def this() {
		this("hey", 33)
		println("---this() ---")
	}

	def this(name:String) {
		this()
		this.name = name
		println("---this(name:String) ---")
	}

	def this(age:Int) {
		this("Gong Tianming")
		this.age = age
		println("---this(age:Int) ---")
	}
	println("-------------constructor ~----------------")

	def show(): Unit = {
		println(s"name=${name}\tage=${age}")
	}
}

1.3. Internal class

The reason why this internal class is mainly used is that if two things, each of which is a class in java, may have an inclusive relationship, such as human Person and heart, which are defined in parallel, it is not in line with the actual situation. Heart is a kind of other things inside people, and can directly access many attributes in people , if you define heart externally, to obtain human blood, you need to create a Person object in heart in parallel, and then perform other operations, which is obviously unreasonable.

  • For this type of operation, we use class nesting to complete the definition, or this structure is called nested class or inner class.
public class InnerClassOps {
    public static void main(String[] args) {
        //Create an object of the Inner class
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.show();
    }
}

class Outer {
    int x = 5;

    class Inner {
        int x = 6;

        public void show() {
            int x = 7;
            System.out.println("x = " + x);
            System.out.println("inner class x = " + this.x);
            System.out.println("Outer class x = " + Outer.this.x);
        }
    }
}

scala version of internal classes

object _03InnerClassOps {
	def main(args: Array[String]): Unit = {
		val outer = new Outer
		val inner = new outer.Inner()
		inner.show()
	}
}

class Outer { ooo =>
	 val x = 5

	class Inner { iii =>
		val x = 6

		def show(): Unit = {
			val x = 7
			System.out.println("x = " + x)
			System.out.println("inner class x = " + iii.x)
			System.out.println("Outer class x = " + ooo.x)
		}
	}
}

1.4. object object

1.4.1. object object

Main functions:

1. Provide the scala class with the entry to run the program and the static main function

2. Provide static members for Scala classes, which are implemented by the accompanying objects of scala classes

scala Internal class of version
```java
object _03InnerClassOps {
	def main(args: Array[String]): Unit = {
		val outer = new Outer
		val inner = new outer.Inner()
		inner.show()
	}
}

class Outer { ooo =>
	 val x = 5

	class Inner { iii =>
		val x = 6

		def show(): Unit = {
			val x = 7
			System.out.println("x = " + x)
			System.out.println("inner class x = " + iii.x)
			System.out.println("Outer class x = " + ooo.x)
		}
	}
}

Summary: the main difference between scala's internal classes and java's internal classes lies in the different creation methods of internal class objects. Secondly, in order to flexibly access internal class members or external class members locally in the internal class, scala can provide an alias for the references of internal and external classes to facilitate operation.

. object object

The main function in java is static. At this time, the main defined in class cannot run, but it can run by replacing class ObjectClassOps with object ObjectClassOps. The main reason is that all members in the structure modified by object are static.

Main functions:

1. Provide the scala class with the entry to run the program and the static main function

2. The scala class is also provided with static members, which are implemented by the accompanying objects of the scala class.

1.4.2. Single case

java singleton

/*
 Hungry Chinese style of single case design mode
 Application scenario: preloading classes, such as program preloading
    The so-called singleton means that this class can only have one instance object
        To achieve this goal, it is to privatize the constructor
    At this time, the instance object of this class cannot be accessed externally
        Therefore, create a static method whose return value is the reference of this class
    In the method created in the second step, the returned instance object of this class needs to be created in advance at the member position of this class
    
*/

calss Singletion{
private Singletion(){}
private static Singletion singletion = new Singletion();
public static Singletion getInstance (){
   return singletion;
}
}

Lazy style - > rote memorization

 class Singleton {
  
  private Singleton(){}
  private int x = 3;
  private static Singleton singleton;
  public static /*synchronized*/ Singleton getInstance() throws InterruptedException {
      if(singleton == null) {
          synchronized (Singleton.class) {
              if(singleton == null) {
                  singleton = new Singleton();
              }
          }
      }
      return singleton;
  }
  }

scala singleton,

object _04SingletonOps {
	def main(args: Array[String]): Unit = {
		val s1 = Singleton.getInstance()
		val s2 = Singleton.getInstance()
		s1.x = 6
		println(s1 == s2)
		println(s1.x)
		println(s2.x)
	}
}
class Singleton private () {
	var x = 5
}
object Singleton {
	private val s = new Singleton
	def getInstance():Singleton = {
		s
	}
}
```

Posted by sethadam1 on Thu, 02 Dec 2021 18:04:58 -0800