Problems with multiple inheritance
Multiple inheritance produces a diamond inheritance problem. Solving problems that can result from multiple inheritance consumes more resources than multiple inheritance yields.
Characteristics
A new feature in JAVA8: Thedefault method, which can be implemented in interface. Scala features a interface similar to Java 8.
The Scala class can inherit only one parent class, but it can be expanded by multiple traits. Scala does not support multiple inheritance, instead it is a trait. Trait can be mixed into related classes as tool methods.
Scala uses traits to achieve the same effect as multiple inheritance. A class can be extended from one or more traits, and a trait can be extended by multiple classes. Traits can limit what classes are extended.
All Java interface can be used as a trait in Scala.
Attributes used as interfaces
Trait Logger { def log (msg:string)}
There is no implements in Scala, so use extends.
Class Consolelogger extends logger{ def log (msg:string) {println (msg)}}
The override keyword is not required in the method of overriding the trait.
If you need more than one trait, you can use the WITH keyword to add additional traits:
Class Consolelogger extends Logger with cloneable with Serializable { //...}
Description: Logger with cloneable with Serializable should be considered as a whole.
Traits with specific implementations
Trait logger{ def log (msg:string) { println (msg) }}
Usage traits
Class Savingaccount extends account with Consolelogger { def withdraw (amount:double) { if (Amount > Balance) Log ("insufficient funds") else balance-= Amount } //...}
In Scala, it is generally said that the function of logger is "mixed" with the Savingaccount class.
overriding abstract methods in attributes
Trait Logger { def log (msg:string)}
Overriding attributes requires the use of override.
Trait Timestamplogger extends Logger { override def log (msg:string) { super.log (new java.util.Date () + "" +msg) }}
The trait is a basic unit of code reuse in Scala, encapsulating the definition of methods and fields.
The definition of the trait uses the reserved word trait, which is similar to the class definition except that it cannot have construction parameters .
Trait reset{ def reset (m:int, n:int) = if (M >= n) 1}
Once the trait is defined, it can be mixed (mixin) into the class.
Class Week extends Reset {...}
When you want to mix multiple traits, take advantage of the WITH keyword:
Class Week extends reset with B with C {...}
The members of a trait can be abstract, and there is no need to use an abstract declaration.
Similarly, the abstract method of overriding the trait does not require an override.
However, multiple traits that override the same trait in an abstract way need to be overridden.
In addition to the inclusion of traits in the class definition, you can also mix traits in a trait definition:
Trait reseting extends reset{...}
To mix attributes when constructing an object:
Val five = new month with reseting
The structure of the trait is sequential: From left to right is constructed.
Constructors are constructed in the following order:
Super class
Parent Trait
The first trait of
The second trait (the parent trait does not repeat the structure)
Class
If class A extends B1 with B2 with B3 ....
So, string B1, B2, B3 ... And the right side wins.
The application of the trait
One of the main applications of the trait is the interface, which automatically adds methods to the class based on the existing methods of the class.
Using attributes to achieve rich interfaces:
Constructs a trait that has a small number of abstract methods and a large number of concrete methods based on abstract methods.
Then, as soon as the trait is mixed into a class, the class overrides the abstract method, and the classes automatically get a lot of concrete methods.
Trait logger{
def log (msg:string)
def warn (msg:string) {log ("server" +msg)}
def server (msg:string) {log ("server" +msg)}
}
Class Week extends logger{
def log (msg:string) {println (msg)}
Server ("HI")
}
Another application aspect of the trait is that it provides stackable changes to the class (super reserved words)
When you add multiple attributes to a class that are called each other, the process starts at the last one.
A method call such as Super.foo () in a class is statically bound and is explicitly called the Foo () method of its parent class.
When Super.foo () is written in a trait, its invocation is dynamically bound. The implementation of a call is determined when each trait is mixed into a specific class.
As a result, the order in which the traits are mixed is different in their execution.
Abstract class Intqueue {def get (): Int;def put (X:int)}
Class Basicintqueue extends Intqueue {
Private Val buf = new Arraybuffer[int]
def get () = Buf.remove (0)
def put (X:int) {buf + = x}
}
Trait incrementing extends Intqueue {
Abstract override def put (X:int) {
Super.put (x + 1)
}
}
Trait doubling extends Intqueue {
Abstract override def put (X:int) {
Super.put (2 * x)
}
}
Object TestClient extends App {
Val queue1 = (new basicintqueue with incrementing with doubling)
Doubling.put (2*2)->incrementing.put (4+1)
Queue1.put (2)
println (Queue1.get ())//result is 5
Val queue2 = (new basicintqueue with doubling with incrementing)
Incrementing.put (2+1)->doubling.put (2*3)
Queue2.put (2)
println (Queue2.get ())//result is 6
}
App features only support single thread. And the normal main can support multithreading.
Extending classes and traits
Constructs an object that extends a class of the specified class and trait, with all the attributes given in the object definition
Scala Basics 07: Traits