Rocking Teen Dream
Video Address: HTTP://WWW.XUETUWUYOU.COM/COURSE/12
The main contents of this section
- This.type use
- Type projection
- Structure type
- Composite type
1. This.type Use
class person { Private varname:string=NULL Private varAge:int=0 defSetName (name:string) ={ This. name=name//Returns the object itself This}defSetage (Age:int) ={ This. age=age//Returns the object itself This}Override defToString () ="Name:"+name+"Age:"+age} Object Main extends App{ //Chained callprintlnNewPerson (). Setage ( -). SetName ("Rocking Teenage Dream"))}
There are some problems with this mechanism when it comes to inheritance, such as:
class person { Private varname:string=NULL Private varAge:int=0 defSetName (name:string) ={ This. name=name//Returns the person object itself This}defSetage (Age:int) ={ This. age=age//Returns the person object itself This}Override defToString () ="Name:"+name+"Age:"+age} class Student extends person { Private varstudentno:string=NULL defSetstudentno (no:string) ={ This. studentno=no This}Override defToString () =Super. toString () +"Studetno:"+studentno} Object Main extends App{ //The code below will error //value Setstudentno is not a member of Cn.scala.xtwy.advancedtype.PersonprintlnNewStudent (). SetName ("John"). Setage ( A). Setstudentno (" the"))}
When the student object calls the SetName, Setage method, the object type returned is essentially the person type, and the person type does not have a Setstudentno method, which compiles an error. To solve this problem, you can set the return value of the SetName, Setage method to: this.type
, the code is as follows:
class person { Private varname:string=NULL Private varAge:int=0 //this.type returns the actual type defSetName (name:string): This.type={ This. name=name//Returns the object itself This}defSetage (Age:int): This.type={ This. age=age//Returns the object itself This}Override defToString () ="Name:"+name+"Age:"+age} class Student extends person { Private varstudentno:string=NULL defSetstudentno (no:string) ={ This. studentno=no This}Override defToString () =Super. toString () +"Studetno:"+studentno} Object Main extends App{ //println (new Person () Setage () setName ("Rocking Teen Dream"))printlnNewStudent (). SetName ("John"). Setage ( A). Setstudentno (" the"))}
2. Type projection
We know that in Scala, the inner class is like a class member, except that it is defined as a type that has the following access creation methods:
class outter { private var x:int=0 //inner class inner class inner { def Test () =x}} Object typeproject extends app { val outter=new outter //the way to create inner classes, as with access to normal member variables val Inner=new outter. Inner println (Inner.test ())}
is the inner class created by different objects in the Scala language the same class? Not really, the following code is proof:
ImportScala.reflect.runtime.universe.typeOf class outter{ Private varX:int=0 defPrint (I:inner) =i class Inner{ defTest () =x}} Object typeproject extends App{ ValOutter=NewOutterValInner=NewOutter. InnerValOutter2=NewOutterValInner2=NewOutter2. Inner//The following code compilation will fail //outter.print (inner2) //This is because the internal class member types that correspond to different outter objects are not the same //This is similar to the memory address of the two class member instances. //The following type judgment will output false //This also shows that they are not the same typeprintln (Typeof[outter. Inner]==typeof[outter2. Inner])}
The type of the parameter in the member method in the Outter class in the code above def print(i:Inner)=i
inner actually equals or, that is, def print(i:this.Inner)=i
it relies on the def print(i:Outter.this.Inner)=i
outer class, and the whole word constitutes a path, because it is also called a path dependency type.
Then look at several uses of the inner class, which correspond to several different path dependency types:
(1) Internal use of the class
class Outter{ privatevar x:Int=0 //内部使用,相当于 //private var i:Inner=new Outter.this.Inner privatevar i:Inner=new Inner def print(i:Inner)=i class Inner{ def test()=x }}
(2) Subclasses use inner classes in the parent class
class Outter{ privatevar x:Int=0 def print(i:Inner)=i class Inner{ def test()=x }}//子类中使用父类中的内部类class A extends Outter{ privateval i=new A.super.Inner}
(3) Use in other classes or objects
object TypeProject extends App{ val outter=new Outter val inner=new outter.Inner val outter2=new Outter val inner2=new outter2.Inner}
After understanding several types of path dependencies, we can describe the type projection: The purpose of type projection is to outter the method def print (I:inner) =i defined in the outer class, which can accept the Inner class in any external class object. In the example above, Outter has a common parent class with the inner type in Outter2. As shown in the following:
The code is as follows:
ImportScala.reflect.runtime.universe.typeOf class outter{ Private varX:int=0 Private varI:inner=NewOutter. This. Innerthe notation of//outter#inner type projection //Can accept inner type objects in any Outter object defPrint (I:outter#inner) =i class Inner{ defTest () =x}} class A extends outter{ Private ValI=NewA.Super. Inner} Object typeproject extends App{ ValOutter=NewOutterValInner=NewOutter. InnerValOutter2=NewOutterValInner2=NewOutter2. Inner//The following statement can be executed successfullyOutter.print (Inner2)//Note that the following statement returns the still false, we are just the Print method in the //parameter for type projection, and does not change outter. Inner and Outter2.inner //are different classes of factsprintln (Typeof[outter. Inner]==typeof[outter2. Inner])}
3. Structure type
A struct type (struture type) adds a dynamic attribute to a static language by using the reflection mechanism, from which the parameter type is not restricted to a named type, for example:
object StructureType { //releaseMemory中的方法是一个结构体类型,它定义了 //一个抽象方法,对close方法的规格进行了说明 def releaseMemory(res:{def close():Unit}){ res.close() } def main(args: Array[String]): Unit = { //结构体使用方式 releaseMemory(new {def close()=println("closed")}) }}
Other struct types can also be declared with the type keyword, such as:
Object structuretype { defReleaseMemory (res:{defClose (): Unit}) {Res.close ()}//Using keywords for struct type declaration typex={defClose (): Unit}//struct type X as type parameter, define function ReleaseMemory2 defReleaseMemory2 (x:x) =x.close ()defMain (args:array[string]): Unit = {ReleaseMemory (New{defClose () =println ("Closed")})//function using the same releasememoryReleaseMemory2 (New{defClose () =println ("Closed")}) }}
From the code above, the struct type can actually be thought of as a class that, when the function is called, creates a struct type object directly from the new operation, and of course it is anonymous. Therefore, the above method can also pass in a class or singleton object that implements the Close method
//Define a common Scala class that contains the close member method class File{ defClose (): Unit=println ("File Closed")}//Define a singleton object, which also contains the close member method Object File{ defClose (): Unit=println ("Object File closed")} Object structuretype { defReleaseMemory (res:{defClose (): Unit}) {Res.close ()}typex={defClose (): Unit}defReleaseMemory2 (x:x) =x.close ()defMain (args:array[string]): Unit = {ReleaseMemory (New{defClose () =println ("Closed")}) ReleaseMemory2 (New{defClose () =println ("Closed")})//For ordinary Scala classes, direct creation of object incoming can use the method described aboveReleaseMemory (NewFile ())//For singleton objects, direct incoming singleton object canReleaseMemory (File)}}
As we can see, although the parameter in the defined method is a struct type, we can also pass in the normal class object and the Singleton object, as long as the object or class has a method declared in the struct type. The above code also tells us that the struct type is also a class, but the expression form and the class are different.
4. Composite type
Compound types in the previous course we've actually had contact, for example
class B extends A with Cloneable
The whole A with cloneable can be thought of as a composite type, which can also be declared with the type keyword, for example:
class B extends A with Cloneableobject CompoundType { //利用关键字type声明一个复合类型 typewith Cloneable def test(x:X)=println("test ok") def main(args: Array[String]): Unit = { test(new B) }}
Add a public number to find out more about the latest spark and Scala technical information
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Getting started with Scala--22nd section Advanced type (i)