Table of contents
Singleton object (companion object):
There are two common ways to create objects:
(1) Use the constructor to construct (new)
Definition of companion object:
There are two types of singleton patterns:
2. Hungry Chinese style: (recommended)
The difference between traits and abstract classes:
Singleton object (companion object):
The Scala language is a fully object-oriented language, so there are no static operations (that is, there is no static concept in Scala). But in order to be able to interact with the Java language (because there is a static concept in Java), a special object is created to simulate a class object, which is a singleton object. If the name of the singleton object is consistent with the name of the class, it is called the companion object of the class of the singleton object, and all "static" content of this class can be placed and declared in its companion object.
There are two common ways to create objects:
(1) Use the constructor to construct (new)
val person0 = new Person09()
(2) Use static methods
(In Scala there is no static method equivalent to object---companion object)
val person01: Person09 = Person09.getPerson()
Definition of companion object:
object Person09{
def getPerson():Person09=new Person09
}
Method 2 is mainly because it cannot be new when the constructor is privatized. In this case, it is necessary to use the companion object construction
class Person09 private{
val name :String="张三"
}
apply method:
In Scala, an apply() method template is introduced to replace the above-mentioned construction method of the companion object. The method is created in the companion object, and the apply method can be called directly in the main method.
The apply() method has been improved in Scala. When the function is called, the method name can not be written, and the method can be called directly.
The call of the apply method:
val person0: Person09 = Person09()
The apply method can also be customized arbitrarily, it is not necessary to create an object like a template
The feature is that you can not write the method name
The apply method can be called directly by Person09()
The system is widely used in collections, calling the apply method of the object
The following collection Array is an object. Using .var to automatically generate objects is actually an Array collection
val ints: Array[Int] = Array(1, 2, 3, 4)
Singleton mode:
The singleton mode is to ensure that a class has only one instance, that is, the object cannot be created casually, so the construction method must be private for privatization and cannot be instantiated by the outside world. This instance is the class member variable of the current class, that is, the class static member variable. This static variable needs to be provided to the outside world, so it is necessary to provide a static method to provide the current instance to the outside world
There are two types of singleton patterns:
1. Lazy style
Occupies less memory (reduces the number of created objects), and is not thread-safe (all enter the if judgment in a certain period of time, all of which are true, and will be assigned to generate variables, which will result in thread safety --- only when it is initialized for the first time)
class Singleton09 private{
}
object Singleton09{ //相当于静态方法 在静态方法中创建对象 便于外边的访问
//先声明属性 先声明为null 后边获取的时候再赋值
private var singleton:Singleton09=null;
def apply(): Singleton09 = {
if (singleton==null)
{
singleton = new Singleton09
}
singleton
}
}
2. Hungry Chinese style: (recommended)
Hungry Chinese style has no thread safety problem, it is easy to write, and takes up a lot of memory (created in advance). It first creates the object in the companion object and loads the class in the jvm, thus avoiding the thread safety problem
object Singleton09 {
private var singleton: Singleton09 = new Singleton09;
def apply(): Singleton09 = singleton
}
Judge the singleton mode:
def main(args: Array[String]): Unit = {
//判断单例模式是否正确
val singleton:Singleton09=Singleton09();
val singleton1:Singleton09=Singleton09();
println(singleton)
println(singleton1)
}
You can see that the address values are the same
Traits:
Basic syntax:
illustrate
class Person11 extends Young11 with old11 with java.io.Serializable{}
(6) Dynamic mix-in: the functions of classes can be flexibly extended
Trait Overlay:
package chapter04
object Test11_TraitMinxin2 {
def main(args: Array[String]): Unit = {
val person1 = new Person12
println(person1.Info())
}
}
trait Age12{
val age:Int
def Info()="age "
}
//下边两个特质均继承自Age12
trait Young12 extends Age12{
override val age: Int = 12
override def Info(): String = super.Info()+"Young "
}
trait Old12 extends Age12{
override val age: Int = 13
override def Info(): String = super.Info()+"Old12 "
}
//钻石效应
class Person12 extends Young12 with Old12 {
override def Info(): String = super.Info()+"Person12 "
}
Test Results:
The above results show that when a diamond problem is generated, it will be called in a sorted order according to the inheritance relationship
When we only want to call the method of a certain class, we can specify the inherited class
The Person12 class has been modified:
class Person12 extends Young12 with Old12 {
override def Info(): String = super[Young12].Info()+"Person12 "
}
Results of the:
The difference between traits and abstract classes:
package chapter04
object Test_14_Rxtends {
def main(args: Array[String]): Unit = {
//多态
var son:father14 =new son14
val son1: son14 = son.asInstanceOf[son14]
son1.sayHi()
}
}
class father14{
}
class son14 extends father14 {
def sayHi(): Unit ={
println("hi son")
}
}