Scala object oriented

Posted by shivam0101 on Mon, 10 Jan 2022 06:01:15 +0100

Scala package

Three functions of Scala package (same as Java)

(1) Distinguish between classes with the same name

(2) When there are many classes, you can manage classes well

(3) Control access scope

 

It shows that Scala has two package management styles,

One method is the same as the package management style of Java. Each source file has a package (the package name and the path where the source file is located do not need to be consistent), and the package name uses "." Separate to represent the hierarchical relationship of packages, such as com atguigu. scala.

Another style represents hierarchical relationships through nested styles, as follows

package com{
package atguigu{
package scala{
}
}
}

(1) Multiple package s can be declared in one source file

(2) The classes in the child package can directly access the content in the parent package without importing the package

package com {
 import com.atguigu.Inner //The parent package needs to be imported to access the child package
 object Outer {
 val out: String = "out"
 def main(args: Array[String]): Unit = {
 println(Inner.in)
 }
 }
 package atguigu {
 object Inner {
 val in: String = "in"
 def main(args: Array[String]): Unit = {
 println(Outer.out) //A child package does not need to import a package to access the parent package
 }
 }
 }
}
package other {
}

 

Package object

In Scala, you can define a package object with the same name for each package, and the members defined in the package object can be accessed directly as the shared variables of all class es and objects under its corresponding package.

(1) If the package management style of Java is used, the package object is generally defined under its corresponding package In the scala file, the package object name is consistent with the package name.

 

(2) if the package is managed in a nested manner, the package object can be defined in the same file as the package, but the package object and the package declaration must be in the same scope.

 

Guide package description

1) Like Java, you can use import at the top, and all classes in this file can be used.

2) Local import: when to use and when to import. It can be used within its scope

3) Wildcard import: import Java util._

4) Name the class: import Java util. {ArrayList=>JL}

5) Import multiple classes of the same package: import Java util. {HashSet, ArrayList}

6) Shielding class: import Java util. {ArrayList =>_,_} 7) Absolute path of import package: New_ root_. java. util. HashMa

 

attribute

Property is a component of a class

[modifier] var|val attribute name [: type] = attribute value

Note: the Bean attribute (@ BeanPropetry) can automatically generate standard setXxx/getXxx methods

package com.atguigu.scala.test
import scala.beans.BeanProperty
class Person {
 var name: String = "bobo" //Define properties
 var age: Int = _ // _Represents a default value for the property
 //Bean Attributes(@BeanProperty)
 @BeanProperty var sex: String = "male"
//val The decorated attribute cannot be assigned a default value, and the specified value must be displayed
}
object Person {
 def main(args: Array[String]): Unit = {
 var person = new Person()
 println(person.name)
 person.setSex("female")
 println(person.getSex)
 }
}

 

encapsulation

Encapsulation is to encapsulate the abstract data and the operation on the data. The data is protected internally. Other parts of the program can operate on the data only through authorized operations (member methods).

The Java encapsulation operation is as follows:,

(1) Privatize properties

(2) Provides a public set method for assigning values to attributes

(3) Provide a public get method to get the value of the property

The public attribute in Scala is actually private at the bottom, and it is operated through the get method (obj.field()) and the set method (obj. Field = (value)).

Therefore, Scala does not recommend setting the property to private and then setting the public get and set methods for it. However, since many Java frameworks use reflection to call getXXX and setXXX methods, sometimes in order to be compatible with these frameworks, getXXX and setXXX methods will be set for Scala properties (implemented through @ BeanProperty annotation).

 

Access rights

In Java, access permissions are divided into public, private, protected and default. In Scala, you can achieve the same effect with similar modifiers. But there are differences in use.

(1) The default access permission of properties and methods in Scala is public, but there is no public keyword in Scala.

(2) Private is a private permission, which is only available in the interior of a class and its associated objects.

(3) Protected is the protected permission. The protected permission in Scala is more strict than that in Java. The same class and subclass can be accessed, but the same package cannot be accessed.

(4) private [package name] adds package access permission. Other classes under the package name can also be used

 

create object

val | var object name [: type] = new ()

(1) val modifies an object. The reference of the object (i.e. memory address) cannot be changed, and the value of the object attribute can be changed.

(2) var modifies an object. You can modify the reference of the object and modify the attribute value of the object

(3) Auto derived variable types cannot be polymorphic, so polymorphic declarations need to be displayed

class Person {
 var name: String = "canglaoshi"
}
object Person {
 def main(args: Array[String]): Unit = {
 //val Modify an object. You can't change the reference (i.e. memory address) of the object. You can change the ownership of the object
The value of the property.
 val person = new Person()
 person.name = "bobo"
 // person = new Person()// FALSE
 println(person.name)
 }
}

 

constructor

Like Java, Scala construction objects also need to call construction methods, and there can be any number of construction methods. Scala class constructors include: main constructor and auxiliary constructor

1)Basic grammar
class Class name(parameter list ) { // primary constructor 
 // Class body
 def this(parameter list ) { // Auxiliary constructor
 }
 def this(parameter list ) { //Auxiliary constructors can have multiple...
 }
}

(1) There can be multiple auxiliary constructors and function names this. The compiler can distinguish them by the number and type of parameters.

(2) Auxiliary construction methods cannot directly build objects, and the main construction method must be called directly or indirectly.

(3) When the constructor calls another constructor, the called constructor must be declared in advance.

(4) If the main constructor has no parameters, the parentheses can be omitted, and the parentheses of the construction method called when building the object can also be omitted.

 class Person(){
    var name: String = _
    var age: Int = _
    def this(age: Int) {
      this()//Calling the main constructor
    this.age = age
    println("Auxiliary constructor 1")
  }
def this(age: Int, name: String) {
  this(age)
  this.name = name
  println("Auxiliary constructor 2")
  }
  println("primary constructor ")
  }
  object Person {
    def main(args: Array[String]): Unit = {
      val person2 = new Person(18,"Zhang San")
    }
  }

Constructor parameters

The formal parameters of the main constructor function of Scala class include three types: without any modification, var modification and val modification

(1) Without any modifiers, this parameter is a local variable

(2) var modifier parameter, used as a member attribute of a class, can be modified

(3) The val modifier parameter is used as a read-only attribute of the class and cannot be modified

def main(args: Array[String]): Unit = {
 var person = new Person("bobo", 18, "male")
 // (1)Without any modifiers, this parameter is a local variable
 // printf(person.name)
 // (2)var Modifier parameter, used as a member attribute of a class, can be modified
 person.age = 19
 println(person.age)
// (3)val Modifier parameter, which is used as a read-only attribute of the class and cannot be modified
 // person.sex = "female"
 println(person.sex)
 }
}

 

Inheritance and polymorphism

1) Basic syntax class subclass name extends parent class name {class body}

(1) Subclasses inherit the properties and methods of the parent class

(2) scala is single inheritance 2)

Case practice

(1) Subclasses inherit the properties and methods of the parent class

(2) Inherited call order: parent class constructor - > child class constructor

class Person(nameParam: String) {
  var name = nameParam
  var age: Int = _
  def this(nameParam: String, ageParam: Int) {
    this(nameParam)
    this.age = ageParam
    println("Parent auxiliary constructor")
  }
  println("Parent class main constructor")
}
class Emp(nameParam: String, ageParam: Int) extends
  Person(nameParam, ageParam) {
  var empNo: Int = _
  def this(nameParam: String, ageParam: Int, empNoParam: Int) {
    this(nameParam, ageParam)
    this.empNo = empNoParam
    println("Auxiliary constructor for subclasses")
  }
  println("Subclass main constructor")
}
object Test {
  def main(args: Array[String]): Unit = {
    new Emp("z3", 11,1001)
  }
}

 

Properties and methods in Scala are dynamically bound, while only methods in Java are dynamically bound. (I don't understand this sentence)

 

abstract class

(1) Define abstract class: abstract class Person {} / / mark the abstract class with the abstract keyword

(2) Define abstract attribute: val|var name:String / / an attribute is an abstract attribute without initialization

(3) Define abstract methods: def hello():String / / methods that are declared but not implemented are abstract methods

abstract class Person {
 val name: String
 def hello(): Unit
}
class Teacher extends Person
{
val name: String = "teacher"
def hello(): Unit = { println("hello teacher")
}
}

 

Inherit & rewrite

(1) If the parent class is an abstract class, the child class needs to implement the abstract properties and methods, otherwise the child class also needs to be declared as an abstract class

(2) Overriding non abstract methods requires overriding, while overriding abstract methods can be done without overriding.

(3) the method of calling the parent class in the subclass uses the super keyword.

(4) The subclass implements the abstract attribute, and the abstract attribute of the parent class can be modified with VaR; The subclass overrides the non Abstract attribute. The non Abstract attribute of the parent class only supports val type, not var. Because VaR is modified as a variable, it can be used directly after subclass inheritance, and there is no need to rewrite it

 

Anonymous subclass

Like Java, you can create an anonymous subclass by including blocks of code with definitions or overrides.

abstract class Person {
 val name: String
 def hello(): Unit
}
object Test {
 def main(args: Array[String]): Unit = {
 val person = new Person {
 override val name: String = "teacher"
 override def hello(): Unit = println("hello teacher")
 }
 }
}

 

Singleton object (companion object)

Scala is a completely object-oriented language, so there is no static operation (that is, there is no static concept in scala). However, in order to interact with the Java language (because there is a static concept in Java), a special object is generated to simulate the class object, which is a singleton object. If the singleton object name is consistent with the class name, it is called the companion object of this class, and all "static" contents of this class can be declared in its companion object.

Basic syntax object Person

{ val country:String="China"

}

(1) The singleton object is declared with the object keyword

(2) The class corresponding to a singleton object is called an associated class, and the name of the associated object should be consistent with the name of the associated class.

(3) The properties and methods in the singleton object can be accessed directly through the associated object name (class name).

//(1)Associated objects adopt object Keyword declaration
object Person {
 var country: String = "China"
}
//(2)The class corresponding to the associated object is called the associated class, and the name of the associated object should be consistent with the name of the associated class.
class Person {
 var name: String = "bobo"
}
object Test {
 def main(args: Array[String]): Unit = {
 //(3)The properties and methods in the associated object can be called directly through the associated object name (class name)
Ask.
 println(Person.country)
 }
}

 

apply method

(1) Through the apply method of the associated object, the implementation does not use the new method to create the object.

(2) If you want the main constructor to be private, you can add private before ().

(3) The apply method can be overloaded.

(4) The obj(arg) statement in Scala is actually calling the apply method of the object, that is, obj apply(arg). To unify the style of object-oriented programming and functional programming.

(5) When you use the new keyword to build an object, you actually call the construction method of the class. When you directly use the class name to build an object, you call the apply method of the real-time associated object.

object Test {
  def main(args: Array[String]): Unit = {
    //(1)By associated objects apply Method, implementation does not use new Keyword to create an object.
    val p1 = Person()
    println("p1.name=" + p1.name)
    val p2 = Person("bobo")
    println("p2.name=" + p2.name)
  }
}
//(2)If you want to make the main constructor private, you can()Before adding private
class Person private(cName: String) {
  var name: String = cName
}
object Person {
  def apply(): Person = {
    println("apply Null parameter called")
    new Person("xx")
  }

  def apply(name: String): Person = {
    println("apply A parameter is called")
    new Person(name)
  }
}

 

Trait

In Scala language, trait trait is used to replace the concept of interface, that is, when multiple classes have the same trait (trait), this trait (trait) can be independent and declared by keyword trait. Traits in scala can have either abstract attributes and methods or concrete attributes and methods. A class can mix multiple characteristics. This feeling is similar to abstract classes in Java. Scala introduces the trait feature. First, it can replace the java interface. Second, it is also a supplement to the single inheritance mechanism.

trait PersonTrait {
 // Declare properties
 var name:String = _
 // Declaration method
 def eat():Unit={
 }
 // Abstract properties
 var age:Int
 
 // Abstract method
 def say():Unit
}
//By looking at the bytecode, you can see the characteristics=abstract class+Interface

Idiosyncratic basic grammar

If a class has a certain trait (feature), it means that the class meets all the elements of the trait (feature). Therefore, the extends keyword is also used. If there are multiple traits or parent classes, the with keyword needs to be used for connection.

1) Basic syntax:

No parent class: class name extends trait 1 with trait 2 with trait 3

Parent class: class name extends parent class with trait 1 with trait 2 with trait 3

2) Explain

(1) Relationship between class and trait: use inheritance relationship.

(2) When a class inherits traits, the first connective is extends, followed by with.

(3) If a class inherits attributes and parent classes at the same time, the parent class should be written after extensions.

3) Case practice(

1) Traits can have both abstract and concrete methods

(2) A class can mix in multiple traits

(3) All Java interfaces can be used as Scala features

(4) Dynamic blending: flexible extension of class functions

(4.1) dynamic blending: when creating an object, the trait is blended without the class being blended into the trait

(4.2) if there are unimplemented methods in the mixed trait, they need to be implemented

trait PersonTrait {
  //(1)Traits can have both abstract and concrete methods
  // Declare properties
  var name: String = _
  // Abstract properties
  var age: Int
  // Declaration method
  def eat(): Unit = {
    println("eat")
  }
  // Abstract method
  def say(): Unit
}
trait SexTrait {
  var sex: String
}
//(2)A class can implement/Inherit multiple traits
//(3)be-all Java Interfaces can be used as Scala Trait use
class Teacher extends PersonTrait with java.io.Serializable {
  override def say(): Unit = {
    println("say")
  }
  override var age: Int = _
}
object TestTrait {
  def main(args: Array[String]): Unit = {
    val teacher = new Teacher
    teacher.say()
    teacher.eat()
    //(4)Dynamic blending: flexible extension of class functions
    val t2 = new Teacher with SexTrait {
      override var sex: String = "male"
    }
    //Call blending trait Properties of
    println(t2.sex)
  }

}

 

Trait superposition

Because a class can mix multiple traits, and there can be specific attributes and methods in the traits, if the mixed traits have the same methods (method name, parameter list and return value are the same), inheritance conflict will inevitably occur.

There are two types of conflicts:

First, two traits (TraitA, TraitB) mixed with a class (Sub) have the same specific methods, and there is no relationship between the two traits. To solve this kind of conflict problem, rewrite the conflict methods directly in the class (Sub).

 

Second, two traits (TraitA, TraitB) mixed with a class (Sub) have the same specific methods, and the two traits inherit from the same trait (TraitC) and the so-called "Diamond problem". Scala adopts the strategy of trait superposition to solve this kind of conflict problem.

 

 

trait Ball {
  def describe(): String = {
    "ball"
  }
}
trait Color extends Ball {
  override def describe(): String = {
    "blue-" + super.describe()
  }
}
trait Category extends Ball {
  override def describe(): String = {
    "foot-" + super.describe()
  }
}
class MyBall extends Category with Color {
  override def describe(): String = {
    "my ball is a " + super.describe()
  }
}
object TestBallTrait {
  def main(args: Array[String]): Unit = {
    println(new MyBall().describe())
  }

}

Trait overlay execution sequence

When a class is mixed with multiple traits, scala will sort all traits and their parent traits in a certain order, and super in this case What describe() calls is actually the describe() method in the next trait in order., The sorting rules are as follows:

 

 

Super in the case does not represent its parent trait object, but the next trait in the above superposition order, that is, super in MyClass refers to Color, super in Color refers to Category, and super in Category refers to Ball. (2) If you want to call a specified method mixed into the trait, you can add a constraint: Super [], such as super [Category] describe().

 

class User(val name: String, val age: Int)
trait Dao {
  def insert(user: User) = {
    println("insert into database :" + user.name)
  }
}
trait APP {
  _: Dao =>
  def login(user: User): Unit = {
    println("login :" + user.name)
    insert(user)
  }
}
object MyApp extends APP with Dao {
  def main(args: Array[String]): Unit = {
    login(new User("bobo", 11))
  }
}

 

Difference between trait and abstract class

Give priority to traits. It is convenient for a class to extend multiple characteristics, but it can only extend one abstract class.

2. If you need constructor parameters, use abstract classes. Because abstract classes can define constructors with parameters, but not characteristics (with or without parameters).

 

Type defines a new type

Use the type keyword to define a new data type name, which is essentially an alias of the type

object Test {
 def main(args: Array[String]): Unit = {
 
 type S=String
 var v:S="abc"
 def test():S="xyz"
 }
}

 

Topics: Scala