17 abstract class and trait
Abstract class:
Abstract classes are similar to Java, except that there is no attribute abstraction in Java, and scala can have attribute abstraction;
Characteristics:
The trait can be understood as an upgraded interface in Java
In Java, interfaces cannot declare properties without values and methods with implementations, while Scala can declare properties without values and methods with implementations;
rewrite:
Rewriting is similar to Java, except that there is no concept of rewriting attributes in Java, while scala can rewrite attributes;
Differences in the use of idiosyncratic and abstract classes:
Only one abstract class can be inherited, but multiple traits can be implemented. This is the same as Java;
The details are described below
17.1 abstract classes
1) When overriding the non abstract members (including fields and methods) of the parent class, the override keyword must be added;
package day03 abstract class Car { // Define common attributes val name:String = "vehicle" // Define abstract attributes (attributes are not assigned) val brand:String // Define common methods def description = { println("This is a common method in an abstract class") } // Define abstract method (method has no method body) def action():Unit } // Defines that a subclass inherits from a parent class class BYDCar extends Car{ // The subclass overrides the abstract member of the parent class, with or without override val brand: String = "BYD" def action(): Unit = { println("The developed blade battery is safer to use") } // If a subclass overrides a non Abstract member of the parent class, override must be added override val name: String = "tram" override def description: Unit = { super.description println(s"${brand} ${name}") action() } } object CarDemo{ def main(args: Array[String]): Unit = { val car = new BYDCar car.description } }
2) If the parent class has a constructor, the main constructor of the child class must call the main constructor or auxiliary constructor of the parent class.
The auxiliary constructor of a subclass cannot call the constructor of a parent class.
package day03 abstract class Car(val color:String) { var price:Double = _ def this(color:String, price:Double) = { this(color) this.price = price } // Define common attributes val name:String = "vehicle" // Define abstract attributes (attributes are not assigned) val brand:String // Define common methods def description = { println("This is a common method in an abstract class") } // Define abstract method (method has no method body) def action():Unit } // Defines that a subclass inherits from a parent class // The subclass main constructor inherits the parent class's main constructor class BYDCar(color:String, types:String) extends Car(color:String){ // The subclass overrides the abstract member of the parent class, with or without override val brand: String = "BYD" def action(): Unit = { println("The developed blade battery is safer to use") } // If a subclass overrides a non Abstract member of the parent class, override must be added override val name: String = "tram" override def description: Unit = { super.description println(s"${brand} ${color} ${types} ${name}") action() } } // An auxiliary constructor that inherits the parent class class WULINGCar(color:String,price:Double, types:String) extends Car(color:String, price:Double){ // Subclasses override the abstract members of the parent class, with or without override val brand: String = "Wuling" def action(): Unit = { println("Popular choice, sales lever drop") } // If a subclass overrides a non Abstract member of the parent class, override must be added override val name: String = "tram" override def description: Unit = { super.description println(s"${brand} ${color} ${types} ${name}") println(s"People friendly price: ${price}") action() } } object CarDemo{ def main(args: Array[String]): Unit = { val car = new BYDCar("Brilliant blue", "Qin Dynasty DMI Oil electric mixing") car.description println("-----------------") val car2 = new WULINGCar("Various colors", 28800,"Agatsuma Mini") car2.description } }
17.2 characteristics
The trait keyword is required to define the trait;
Traits can contain abstract members and non abstract members, which is similar to scala's abstract class. When abstract members are included, the abstract keyword is not required;
In Scala, the extends keyword is used for both inherited classes and inherited traits;
When rewriting the method of attributes, there is no need to give the override keyword;
package day03 trait Fly { // Define common attributes val name:String = "fly" // Define abstract properties val maxFlyHigh:Int // Define common methods def description = { println("This is the common method in traits") } // Define abstract methods def action():Unit } class Bird extends Fly{ // Override abstract member val maxFlyHigh: Int = 1000 def action(): Unit = { println("Birds fly with their wings") } // Override non abstract members override val name: String = "Flamingo" override def description: Unit = { super.description println(s"${name}") action() println(s"Maximum flight altitude: ${maxFlyHigh}") } } object TraitTest{ def main(args: Array[String]): Unit = { val bird = new Bird bird.description } }
When you do not inherit a class and directly implement a trait, you can use extensions instead of with. When you implement multiple traits, you can use multiple with, but you must first extend the first one
For example, class T1 extends T2 with T3 with T4
package day03 trait Fly { // Define common attributes val name:String = "fly" // Define abstract properties val maxFlyHigh:Int // Define common methods def description = { println("This is the common method in traits") } // Define abstract methods def action():Unit } trait Run{ def run():Unit } class Bird extends Fly{ // Override abstract member val maxFlyHigh: Int = 1000 def action(): Unit = { println("Birds fly with their wings") } // Override non abstract members override val name: String = "Flamingo" override def description: Unit = { super.description println(s"${name}") action() println(s"Maximum flight altitude: ${maxFlyHigh}") } } // Realize multiple characteristics with class AirPlane extends Fly with Run{ override val maxFlyHigh: Int = 10000 override def action(): Unit = { println("Planes fly with wings") } override def run(): Unit = { println("The plane runs on wheels") } override def description: Unit = { super.description action() run() println(s"Maximum flight altitude: ${maxFlyHigh}") } } object TraitTest{ def main(args: Array[String]): Unit = { val bird = new Bird bird.description println("------------------") val plane = new AirPlane plane.description } }
Characteristics realize the logic of construction through the initialization of fields and the composition of statements in other characteristics.
But you cannot new instances.
trait T1{ // Trait construction execution val a:String = "aaa" println(a) def t1():Unit } trait T2{ // Trait construction execution val b:String = "bbb" println(b) def t2():Unit } class T1Sub extends T1 with T2{ //This type of construction execution val c:String = "ccc" println(c) def t1():Unit={ println("do t1()") } def t2():Unit={ println("do t2()") } } object T1SubTest{ def main(args: Array[String]): Unit = { // When calling new T1Sub, execute the construction of T1 first, then T2, and then this kind of construction val t = new T1Sub t.t1() t.t2() } } //-----------Operation results----------------- aaa bbb ccc do t1() do t2()
When to use idiosyncratic and abstract classes?
Use angle
Abstract classes are used for primary and secondary relations, and traits are used for additional functions, such as spider man.
Grammatical Perspective
1) 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 attributes.
Original article of Haiyu tribe, original link: http://hainiubl.com/topics/75749