Characteristics
The Java interface in Scala is trait (feature). It's actually more powerful than the interface. Unlike interfaces, it can also define the implementation of properties and methods. Features in Scala are used to serve the modularity of a single-purpose functional module. Scala is designed to meet the functional requirements of various applications by blending this feature (module) group.
The structural order of traits
A trait can also have a constructor, consisting of the initialization of the field and the statements in the other trait body. These statements are executed at the time of construction of any object that is mixed with that trait.
The execution order of the constructors:
- Call the constructor of the superclass;
- The trait constructor executes after the superclass constructor, before the class constructor;
- The trait is constructed from left to right;
- Among each trait, the parent trait is first constructed;
- If multiple traits share a parent trait, the parent trait is not repeated
- All traits are constructed and subclasses are constructed.
The order of the constructors is the inverse of the linearization of the class. Linearization is a technical specification that describes all the super types of a type.
As a feature of stackable change
One of the main uses of traits is to turn thin interfaces (with fewer methods) into fat interfaces (there are more methods).
Its second main usage is to provide stackable changes to the class.
Consider an example of an integer queue. The queue has two operations: put, put an integer into the queue, get, take an integer from the tail.
import scala.collection.mutable.ArrayBufferabstractclass IntQueue { def get(): Int def put(x: Int)}class BasicIntQueue extends IntQueue { privatevalnew ArrayBuffer[Int] def get() = buf.remove(0) def put(x: Int) = { buf += x }}
Suppose the defining trait performs the following changes:
- Doubling: Doubles all numbers placed in the queue
- Incrementing: Adds all the numbers placed in the queue
- Filtering: Filter out negative integers from the queue
These three traits represent changes because they change the behavior of the original queue class instead of defining a completely new queue class. These three traits are stackable, and you can choose to blend them into the class to get the new class that you want to change.
//overriding abstract methods in attributes trait doubling extends intqueue { Abstract Override defPut (X:int) {Super. put (2*X)}} trait incrementing extends intqueue { Abstract Override defPut (X:int) {Super. put (x+1) }} trait Filtering extends intqueue { Abstract Override defPut (X:int) {if(x >=0)Super. put (x)}}
Explanation: The above code defines the superclass Intqueue, which means that the trait can only be mixed into the extended Intqueue class .
In the trait, there is a super call in the abstract method, which is dynamically bound when super is called in the trait, whereas in the class, the super call is illegal because of the inherited abstract class. The abstract override identifier must be used here, which means that the trait must be mixed into a class with a specific definition of the expected method, which is used only in the definition of the trait.
Demonstrate:
Scala>ValQueue =NewBasicintqueue withDoublingqueue:basicintqueue withdoubling = $anon $1@1D3eff4scala> Queue.put (Ten) scala> queue.get () Res10:int = -ValQueue =NewBasicintqueue withDoubling withIncrementingqueue:basicintqueue withDoubling withincrementing = $anon $1@ +De304scala> Queue.put (-1) scala> Queue.put (2) scala> Queue.put (3) Scala> queue.getres3:Int =0Scala> queue.getres4:Int =6Scala> queue.getres5:Int =8
The order of mixing is important, and the closer to the right is the first thing to work. When you call a method with a class that is mixed in, the method of the rightmost trait is called first. If that method calls super, it invokes the method of its left trait, and so on. in the example above, incrementing's put is called first, and then the second doubing put is called.
Characteristic linearization and multi-integration
A trait is a way to inherit multiple structures similar to a class, but it is very important to distinguish it from multiple inheritance. One of them is particularly important: the super explanation.
For multiple inheritance, a method call resulting from a super call can be explicitly determined where the call takes place, and for the trait, the method invocation is determined by the linearization (linearization) of the class and the trait that is blended into the class. This distinction makes it possible to stack the above traits.
In multiple-inheritance languages, the same method is called, and the compilation rule determines which superclass will eventually win, and calls the specified method of the superclass.
In Scala, when you instantiate a class with new, Scala puts the class and all the classes it inherits and his traits in a linear order. Then, when you call super in one of these classes, the method being called is the next section of the method chain. In addition to the last method of calling super, the net result is a stackable behavior.
Linearization Details
The main attributes of Scala's linearization can be demonstrated in the following example: Suppose you have a class Cat that inherits from the superclass Animal and two traits furry and fourlegged. Fourlegged also expands another trait Haslegs:
class Animal trait furry extends Animal trait haslegs extends Animal trait fourlegged extends haslegs class Cat extends Animal with furry with Fourlegged
The inheritance hierarchy and linearization order of class Cat are shown in. The inheritance order is indicated by traditional UML annotations: The white arrows indicate inheritance, and the arrows point to the super type. The black arrows illustrate the linearization order, and the arrows point to the direction that super calls to resolve.
When any one of these classes and traits calls the method through super, the invoked implementation will be the first implementation on the right side of its linearization.
Resources
Scala Learning--traits
reprint Please indicate the author Jason Ding and its provenance
Gitcafe Blog Home page (http://jasonding1354.gitcafe.io/)
GitHub Blog Home page (http://jasonding1354.github.io/)
CSDN Blog (http://blog.csdn.net/jasonding1354)
Jane Book homepage (http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google search jasonding1354 go to my blog homepage
The linearization of "Scala" traits and traits