敏捷硬件开发语言Chisel与数字系统设计 课件 第12章 Scala面向对象编程_第1页
敏捷硬件开发语言Chisel与数字系统设计 课件 第12章 Scala面向对象编程_第2页
敏捷硬件开发语言Chisel与数字系统设计 课件 第12章 Scala面向对象编程_第3页
敏捷硬件开发语言Chisel与数字系统设计 课件 第12章 Scala面向对象编程_第4页
敏捷硬件开发语言Chisel与数字系统设计 课件 第12章 Scala面向对象编程_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

12.Scala面向对象编程一、类和对象二、操作符即方法三、类继承四、特质目录2一、类和对象3面向过程编程类和对象面向对象编程什么是面向对象编程?万物皆对象!医嘱、护士、病人、手、皮肤、血管、消毒水、空气……4面向过程编程类和对象面向对象编程什么是面向对象编程?需求:把大象小胖装进冰箱小冰void小冰开门(){}void小胖进小冰(){}void小冰关门(){}Intmain(){

小冰开门();小胖进小冰();小冰关门();}class冰箱{def开门(){}def关门(){}}class大象{def进入(d:String){}}object大象进冰箱{defmain(args:Array[String]):Unit={val小胖=new大象val小冰=new冰箱

小冰.开门

小胖.进入(小冰)小冰.关门}}5为什么选面向对象编程?面向过程编程ProcedureOriented

一、类和对象面向对象编程

ObjectOriented

///jerry11112/article/details/79027834易维护、易复用、易扩展一些情景下性能比面向对象高6类:一个模板,它描述一类对象的行为和状态。对象:类的一个实例,具体的事物。类是创建对象的模板,对象是类的实例

一、类和对象1.1类🐕类:狗状态:颜色,名字,品种行为:吃,叫,摇尾巴对象2颜色:黑白名字:二毛品种:哈士奇类与对象的概念对象1颜色:黄白名字:大旺品种:中华田园7类里有什么?一、类和对象🐕类:狗字段:颜色,名字,品种方法:吃,叫,摇尾巴1.1类方法:用“def”定义的函数,是对象具有的行为成员构造对象时,操作系统会分配存储给每个对象来放自己的字段,但不需要为某个对象单独保存其方法!字段:val或var类型的变量,保存对象的状态或数据8例如:一、类和对象[修饰符]

class类名{

类体}1.1类一般不加,省略时是默认类具有公有可见的classStudents{

varname="None"

varage:Int=_

varscore:Double=_

defregister(n:String,a:Int,sc:Double):Unit={

name=n

age=a

score=sc

}

}定义类Students申明字段,必须显示的初始化定义方法register定义类9一、类和对象创建对象说明:val类型的变量只能与初始化时的对象绑定,不能再被赋予新的对象。Scala

在创建对象时,类型声明可以省略。一般一个对象的类型,就是这个类。val对象名[:类型]=new

类名()1.1类10一、类和对象访问对象成员对象名.字段名1.1类对象名.方法名scala>classStudents{

|privatevarname="None"

|defregister(n:String)=name=n

|defdisplay()=println(name)

|}

definedclassStudents

scala>valstu=newStudents

stu:Students=Students@15a7e51

scala>stu.register("Bob")

scala>

^

error:variablenameinclassStudentscannotbeaccessedinStudents

scala>stu.display()

Bob只可访问公有的类成员(默认公有),外部不可访问private修饰的类成员创建对象并赋给变量stu调用方法register外部访问字段name11一、类和对象1.2类的构造方法主构造方法不需要显式定义

,类内部非字段、非方法的代码都是“主构造方法”。类名后面可以定义若干个参数列表,用于接收参数,参数将在构造对象时用于初始化字段并传递给主构造方法使用。需求:如果想在创建Sutdents的对象时直接指定这个对象的姓名,该怎么做?

是一种特殊的方法,用于完成对新对象的初始化。构造方法类的构造方法主构造方法辅助构造方法12一、类和对象举例:1.2类的构造方法scala>classStudents(n:String){

|valname=n

|println("Astudentnamed"+n+"hasbeenregistered.")

|}

definedclassStudents

scala>valstu=newStudents("Tom")

AstudentnamedTomhasbeenregistered.

stu:Students=Students@5464eb28主构造方法Students类接收一个String参数n,并用n来初始化字段name主构造方法构造对象时初始化字段name并调用主构造方法13一、类和对象1.2类的构造方法辅助构造方法目的:任何构造方法最终都调用该类的主构造方法,使主构造方法成为类的单一入口。以“defthis(......)”来开头;一个类内可以有多个辅助构造方法,编译器通过不同参数来区分不同的辅助构造方法。第一步行为必须是调用该类的主构造方法或其它的辅助构造方法。字段或方法“当前”所在的对象14一、类和对象举例:以“defthis(......)”开头构造方法通过参数区分第一步调用主构造方法或另一个辅助构造方法请同学们思考在构造stu这个对象时是调用了哪个构造方法呢?scala>classStudents(n:String){

|valname=n

|defthis()=this("None")

|println("Astudentnamed"+n+"hasbeenregistered.")

|}

definedclassStudents

scala>valstu=newStudents

AstudentnamedNonehasbeenregistered.

stu:Students=Students@1cf39c6调用主构造方法辅助构造方法1.2类的构造方法辅助构造方法15一、类和对象举例:在类名与类的参数列表之间加上关键字“private”,那么主构造方法就是私有的。scala>classStudentsprivate(n:String,m:Int){

|valname=n

|valscore=m

|defthis(n:String)=this(n,100)

|println(n+"'sscoreis"+m)

|}

definedclassStudents

scala>valstu=newStudents("Bill",90)

^

error:toomanyarguments(2)forconstructorStudents:(n:String)Students

scala>valstu=newStudents("Bill")Bill'sscoreis100

stu:Students=Students@4c3ed51.2类的构造方法私有主构造方法外部代码构造对象时不能通过主构造方法进行,而必须使用其他公有的辅助构造方法或工厂方法(专门用于构造对象的方法)16一、类和对象1.3类参数类参数也是主构造方法的形参无修饰符修饰:仅仅是参数,一个局部变量。val或var修饰:在类的内部会生成一个与参数同名的公有字段,

构造对象时,这些参数会直接复制给同名字段。classPerson(valsex:String){

}sex不仅仅是参数还是类的公有字段,相当于在类内定义了valsex,其值可以在构造对象时被传入17一、类和对象1.3类参数举例:scala>classStudents(valname:String,varscore:Int){

|defexam(s:Int)=score=s

|overridedeftoString=name+"'sscoreis"+score+"."

|}

definedclassStudents

scala>valstu=newStudents("Tim",90)

stu:Students=Tim'sscoreis90.

scala>stu.exam(100)

scala>stu.score

res0:Int=100不仅为类参数,还是类成员可以在外部通过对象访问18一、类和对象1.4方法重载方法重载:在类里定义了多个同名的方法,但是每个方法的参数不一样。这些方法虽然同名,但是它们是不同的。方法重载是面向对象里多态属性的一种表现。classAdder{

defadd(a:Int,b:Int){

varsum=a+b

println(sum)

}

defadd(a:Int,b:Int,c:Int){

varsum=a+b+c

println(sum)

}

}在Adder类中有两个版本的add方法19一、类和对象1.5单例对象与伴生对象单例对象:用“object”开头定义一个对象。伴生对象、伴生类:单例对象&同名类C++、Java等语言:类内可以有静态变量(不属于某个对象,是所有对象共有的)Scala:纯粹的面向对象属性,无静态操作的概念为什么会有单例对象?存放静态变量和方法作为程序的入口打包某方面功能的函数系列成为一个工具集伴生类和伴生对象必须在同一个文件里,两者可以互访对方的所有成员。单例对象的作用20一、类和对象1.6工厂对象与工厂方法工厂方法:专门用来构造某一个类的对象的方法。工厂对象:包含这些工厂方法集合的单例对象。用法:工厂方法通常定义在伴生对象里。尤其是当一系列类存在继承关系时,可以在基类的伴生对象里定义一系列对应的工厂方法。作用:不用直接使用new来实例化对象,改用方法调用。对外隐藏了类的实现细节!21一、类和对象1.6工厂对象与工厂方法//students.scala

classStudents(valname:String,varscore:Int){

defexam(s:Int)=score=s

overridedeftoString=name+"'sscoreis"+score+"."

}

objectStudents{

defregisterStu(name:String,score:Int)=newStudents(name,score)

}将文件students.scala编译后,在解释器中可以这样使用:scala>importStudents._

importStudents._

scala>valstu=registerStu("Tim",100)

valstu:Students=Tim'sscoreis100.导入单例对象调用工厂方法来构造Students类的对象类Students的伴生对象,即工厂对象工厂方法22一、类和对象1.7apply方法用法:在伴生对象里定义名为apply的工厂方法,就能通过“伴生对象名(参数)”来构造一个对象。在类里定义一个与类相关的、具有特定行为的apply方法,让使用者可以隐式调用,进而隐藏相应的实现细节。对象.apply(参数)显式调用对象(参数)隐式调用如果apply是无参方法,必须写出空括号!类和单例对象,都能定义apply方法23一、类和对象1.7apply方法//students2.scala

classStudents2(valname:String,varscore:Int){

defapply(s:Int)=score=s

defdisplay()=println("Currentscoreis"+score+".")

overridedeftoString=name+"'sscoreis"+score+"."

}

objectStudents2{

defapply(name:String,score:Int)=newStudents2(name,score)

}将文件students2.scala编译后,就能在解释器里这样使用:scala>valstu2=Students2("Jack",60)

valstu2:Students2=Jack'sscoreis60.

scala>stu2(80)

scala>stu2.display()

Currentscoreis80.用伴生对象的工厂方法来构造对象类中定义apply方法伴生对象中定义apply的工厂方法调用类中apply方法24一、类和对象1.8小结面向对象编程的思想类、对象、方法、字段的概念和定义的语法类参数的概念、用类的构造方法来构造对象单例对象与伴生对象工厂对象与工厂方法apply方法25二、操作符即方法262.1操作符在Scala里的解释基本类型:byte、short、int、char、float等操作符:+、-、*等二、操作符即方法C++、Java等“classByte”、“classShort”、“classChar”、“classInt”、“classLong”、“classFloat”、“classDouble”、“classBoolean”和“classUnit”九种值类定义在“classInt”、“classDouble”等类里的成员方法Scala追求纯粹的面向对象,万物皆对象!抽象的、不可继承的、对象由字面量表示272.1操作符在Scala里的解释二、操作符即方法Int对象“1”调用了它的成员方法“+”,并把Int对象“2”当作参数传递给了该方法,最后这个方法会返回一个新的Int对象“3”1+21.+(2)scala>classStudents3(valname:String,varscore:Int){

|defexam(s:Int)=score=s

|deffriends(n:String,s:Int)=println("Myfriend"+n+"gets"+s+".")

|overridedeftoString=name+"'sscoreis"+score+"."

|}

classStudents3

scala>valstu3=newStudents3("Alice",80)

valstu3:Students3=Alice'sscoreis80.

scala>stu3exam100

scala>stu3.score

valres0:Int=100

scala>stu3friends("Bob",70)

MyfriendBobgets70.方法调用都能写成操作符的形式:去掉句点符号,并且方法参数只有一个时可以省略圆括号。28二、操作符即方法2.2三种操作符前缀操作符写在操作数前面操作数只有一个一个无参方法,操作数是调用该方法的对象前缀操作符只有“+”、“-”、“!”和“~”四个,相对应的方法名分别是“unary_+”、“unary_-”、“unary_!”和“unary_~”;如果自定义的方法名是“unary_”加上这四个操作符之外的操作符,那么就不能写成前缀操作符的形式。eg.定义了方法“unary_*”*p

p.unary_*

punary_*×√√29二、操作符即方法2.2三种操作符中缀操作符左右两边都接收操作数两个操作数中的一个是调用该方法的对象,一个是传入该方法的参数普通的有参方法参数那一边没有数量限制,只是多个参数需要放在圆括号里;以冒号“:”结尾的操作符,其右操作数是调用该方法的对象,其余操作符都是把左操作数当调用该方法的对象。30二、操作符即方法2.2三种操作符后缀操作符写在操作数后面的操作符并且操作数只有一个,即调用该方法的对象无参方法方法名如果构成前缀操作符的条件,那么既可以写成前缀操作符,也可以把完整的方法名写成后缀操作符。方法是“unary_+”、“unary_-”、“unary_!”和“unary_~”312.3操作符的优先级和结合性二、操作符即方法优先级通过方法名的首个字符来比较优先级前缀操作符的方法名要去掉关键字圆括号内的优先级最高1+++2***31+++(2***3)322.3操作符的优先级和结合性二、操作符即方法优先级如果操作符以等号结尾,并且不是“>=”、“<=”、“==”或“!=”四个比较操作符之一,那么就认为是赋值操作符,优先级最低。sum*=1+2sum*=(1+2)例外“*=”的优先级并不会因为以“*

”开头就比“+”高,而是被当作了一种赋值操作332.3操作符的优先级和结合性二、操作符即方法结合性一般情况,同级的操作符:从左往右结合以冒号结尾的中缀操作符:从右往左结合a+b+c+d((a+b)+c)+da:::b:::c:::da:::(b:::(c:::d))例如:好的编程习惯:在操作符的结合顺序不能一眼就看明白时,最好加上圆括号来表示前后顺序!342.4预设操作符二、操作符即方法+算术加法-算术减法*算术乘法/算术除法%算术取余>

大于<

小于>=大于等于<=小于等于==等于!=不等于&&、&逻辑与,前者短路,后者不短路||、|逻辑或,前者短路,后者不短路!逻辑非&位与|位或^位异或~位取反>>

算术右移<<

左移>>>

逻辑右移352.5对象的相等性二、操作符即方法自然相等性:字面上的值相等,就认为两个对象相等。引用相等性:构造的对象常常会赋给一个变量,即让变量引用该对象。引用相等性用于比较两个变量是否引用了同一个对象。用“==”和“!=”比较用“eq”和“ne”比较思考:两个变量引用了两个完全一样的对象,两种相等性分别是什么?自然相等性:true引用相等性:false36二、操作符即方法举例:2.5对象的相等性scala>vala=List(1,0,-1)

vala:List[Int]=List(1,0,-1)

scala>valb=List(1,0,-1)

valb:List[Int]=List(1,0,-1)

scala>valc=List(1,0,1)

valc:List[Int]=List(1,0,1)

scala>vald=a

vald:List[Int]=List(1,0,-1)scala>a==c

valres0:Boolean=false

scala>a==b

valres1:Boolean=true

scala>aeqb

valres3:Boolean=false

scala>aeqd

valres4:Boolean=true37二、操作符即方法2.6小结介绍了“操作符即方法”这个重要概念。熟悉了三种操作符的定义和使用学习了操作符的优先级和结合性两种对象相等性的判断38三、类继承393.1Scala的类继承三、类继承节省代码量的两种策略:包含和继承。包含:

“hasa”一个类包括了另一个类的实例403.1Scala的类继承三、类继承节省代码量的两种策略:包含和继承。继承:

“isa”从一个宽泛的类可以派生出更加具体的类生物植物动物狗猫鸭超类超类子类子类413.1Scala的类继承三、类继承从一个宽泛的类可以派生出更加具体的类class子类名

extends

超类名

{

类体

}继承的基本语法被继承的类称为“超类”,而派生出来的类称为“子类”。如果继承层次较深,最顶层的类通常也叫“基类”。超类的超类也叫超类,子类的子类还叫子类。子类可以继承超类的字段和方法。423.1Scala的类继承三、类继承class子类名

extends

超类名

{

类体

}scala>classA{

|vala="ClassA"

|}

classA

scala>classBextendsA{

|valb="ClassBinheritsfromA"

|}

classB

scala>valx=newB

x:B=B@1919e19

scala>x.a

res0:String=ClassA

scala>x.b

res1:String=ClassBinheritsfromA定义子类B继承自超类A433.2调用超类的构造方法三、类继承子类调用超类的构造方法的语法class子类(子类对外接收的参数)extends

超类(子类给超类的参数)在构造某个类的对象时,如果这个类继承自另外一个类,那么应该先构造超类对象的组件,再来构造子类的其他组件。超类构造方法继承的构造方法调用顺序:子类构造方法443.2调用超类的构造方法三、类继承超类构造方法继承的构造方法调用顺序:子类构造方法scala>classA(vala:Int)

classA

scala>classB(giveA:Int,valb:Int)extendsA(giveA)

classB

scala>valx=newB(10,20)

x:B=B@14e554f

scala>x.a

res0:Int=10

scala>x.b

res1:Int=20class子类(子类对外接收的参数)extends

超类(子类给超类的参数)453.3重写超类的成员三、类继承金属超类中的某个属性可能并不一定符合子类的情况,子类需要一个新的符合子类行为的版本。固态液态重写override成员定义

重写超类的成员的语法防止意外的重写改善了“脆弱基类”的问题463.3重写超类的成员三、类继承不可重写的成员无参方法与字段final超类成员子类不可重写final类类不可被继承Scala在调用无参方法和调用同名的字段时形式相同无参方法字段重写不能重写方法的返回类型必须和字段的类型一致!473.3重写超类的成员三、类继承无参方法字段重写不能重写scala>classA{

|defjustA()="A"

|}

classA

scala>classBextendsA{

|overridevaljustA="B"

|}scala>classD{

|vald=10

|}

classD

scala>classEextendsD{

|overridedefd()=100

|}将无参方法重写为字段将字段重写为无参方法×√483.4子类型多态与动态绑定三、类继承子类型多态:类型为超类的变量可以指向子类的对象。对于方法:尽管变量的类型是超类,方法的版本却是“动态绑定”的。调用的方法要运行哪个版本,是由变量指向的对象来决定的scala>classA{

|defdisplay()="I'mA."

|}

classA

scala>classBextendsA{

|overridedefdisplay()="I'mB."

|}

classB

scala>valx:A=newB

valx:A=B@6ebece

scala>x.display()

valres0:String=I'mB.变量x的类型为超类A,但指向的对象为子类B的对象493.5抽象类三、类继承如果类里包含了没有具体定义的成员——没有初始化的字段或没有函数体的方法,那么这个类就是抽象类,必须用关键字“abstract”修饰。存在抽象成员:不能构造出具体的对象,不能用“new”初始化!(抽象类)超类成员:抽象子类成员:具体子类实现超类的抽象成员子类实现超类的抽象成员时,关键字“override”可写可不写。503.5抽象类三、类继承objectAbstractClass{

defmain(args:Array[String]):Unit={

//valx=newJ//抽象类不能通过“new”来构造实例对象

//error:classJisabstract;cannotbeinstantiated

valy=newK(1)

//构造子类的对象

println(y.j)//访问被子类“实现”了超类的抽象成员j

println(y.k)//输出:1

}

}

abstractclassJ{//定义抽象类J

valj:Int//声明了抽象成员,没有”定义“

}

classK(valk:Int)extendsJ{//定义子类K

valj=k*2//子类“实现”了超类的抽象成员j

}513.6Scala类的层次结构三、类继承/tour/unified-types.html抽象类,是所有类的超类值类引用类自定义的类Null:空引用,即指向JVM里的空内存Nothing:所有值类和引用类的子类,甚至还是Null类的子类。不仅表示空引用,还表示空值523.6Scala类的层次结构三、类继承/tour/unified-types.html值类的隐式转换scala>valx:Long=987654321

x:Long=987654321

scala>valy:Float=x

y:Float=9.8765434E8

scala>valz:Long=y

<console>:12:error:typemismatch;用于对象在两个类之间进行类型转换53三、类继承3.7小结类继承的概念和方法子类调用超类的构造方法重写超类的成员子类型多态与动态绑定抽象类Scala类的层次结构在编写Chisel时,类继承主要用于编写接口,使接口可以扩展!54四、特质554.1什么是特质四、特质特质天生就是抽象的,可以包含抽象成员;但是不需要用“abstract”修饰,也不能用“new”来实例化。特质内部可以包含字段和方法,甚至包含其他单例对象、类和特质的定义。单例对象、类、和特质都可以混入特质,也可以用“override”来重写特质成员。Scala只允许继承自一个类,但是对特质的混入数量却没有限制。56scala>classA{

|vala="ClassA"

|}

definedclassA

scala>traitB{

|valb="TraitB"

|}

definedtraitB

scala>objectCextendsAwithB

definedobjectC

scala>C.a

res1:String=ClassA

scala>C.b

res2:String=TraitB

4.1什么是特质四、特质单例对象、类以及特质在混入一个特质后,就包含了特质的所有公有成员。代码举例:可以用关键字“extends”继承类或混入特质;当混入多个特质时,后续关键字使用“with”。特质的定义使用关键字“trait”,且不能有入参。574.2特质的层次四、特质特质也可以继承自其他类,或混入任意个特质。在特质没有继承和混入时,那么这个特质就是AnyRef类的子特质。当某个类、单例对象或特质用关键字“extends”混入一个特质时,会隐式继承自这个特质的超类。特质对混入有一个限制条件:类、单例对象和特质混入特质时,它们的超类必须是待混入特质的超类,或者是待混入特质的超类的子类。58scala>classA

scala>classBextendsA

scala>classC

scala>traitDextendsA

scala>traitEextendsB

scala>classTest1extendsAwithD

definedclassTest1

scala>classTest2extendsBwithD

definedclassTest24.2特质的层次四、特质代码举例:特质D继承自类A特质E继承自类B类Test1的超类是类A特质D的超类也是类A类Test2的超类是类B,也就是A的子类特质D的超类也是类A59scala>classA

scala>classBextendsA

scala>classC

scala>traitDextendsA

scala>traitEextendsB

scala>classTest3extendsCwithD

<console>:13:error:illegalinheritance;superclassCisnota

subclassofthesuperclassAofthemixintraitD

classTest3extendsCwithD

^4.2特质的层次四、特质代码举例:类Test3的超类是类C特质D的超类的类A604.3混入特质的简便方法四、特质还可以在最前面加上一个想要继承的超类:newTrait1withTrait2...{definition}newSuperClasswithTrait1withTrait2...{definition}实际上,此处定义了一个匿名类等效代码:classAnonymousClassextendsTrait1withTrait2...{definition}

newAnonymousClass614.3混入特质的简便方法四、特质代码举例:scala>traitA{

|vala="IcomefromtraitA!"

|}

definedtraitA

scala>traitB{

|valb="IcomefromtraitB!"

|}

definedtraitB

scala>valC=newAwithB

C:AwithB=$anon$1@5a058be5

scala>C.a

res0:String=IcomefromtraitA!

scala>C.b

res1:String=IcomefromtraitB!624.4特质的线性化叠加计算四、特质需要在特质里定义同名同参的方法,并用关键字组合“abstractoverride”修饰。特质对该方法的定义必须出现“super.方法名(参数)”。abstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}

traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}

traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}

traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}

classGextendsX{overridedefm(s:String)="G->"+s}

valx=newGwithDwithEwithFwithB

println(x.m("End"))//G->D->C->E->F->B->End634.4特质的线性化叠加计算四、特质abstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}

traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}

traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}

traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}

classGextendsX{overridedefm(s:String)="G->"+s}

valx=newGwithDwithEwithFwithB

println(x.m("End"))//G->D->C->E->F->B->End该特质必须混入某个拥有该方法具体定义的类中。需要混入特质进行线性化计算的类,在定义时不能立即混入特质。644.5线性化计算公式四、特质①G根据线性化计算公式得:abstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}

traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}

traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}

traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}

classGextendsX{overridedefm(s:String)="G->"+s}

valx=newGwithDwithEwithFwithB

println(x.m("End"))//G->D->C->E->F->B->End最左边是类本身。654.5线性化计算公式四、特质①G②G→B→A根据线性化计算公式得:蓝色表示起点,类X不参与计算abstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}

traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}

traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}

traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}

classGextendsX{overridedefm(s:String)="G->"+s}

valx=newGwithDwithEwithFwithB

println(x.m("End"))//G->D->C->E->F->B->End类的右边写定义时最后混入的特质,并接着往右按继承顺序写该特质的所有超类和超特质。664.5线性化计算公式四、特质①G②G→B→A③G→B→A→F→C→A④G→B→A→F→C→A→E→C→A⑤G→B→A→F→C→A→E→C→A→D→A根据线性化计算公式得:蓝色表示起点,红色表示重复,类X不参与计算abstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}

traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}

traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}

traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}

classGextendsX{overridedefm(s:String)="G->"+s}

valx=newGwithDwithEwithFwithB

println(x.m("End"))//G->D->C->E->F->B->End继续往右写下倒数第二个混入的特质,以及其超类和超特质,直到写完所有特质。674.5线性化计算公式四、特质①G②G→B→A③G→B→A→F→C→A④G→B→A→F→C→A→E→C→A⑤G→B→A→F→C→A→E→C→A→D→A⑥G→B→F→E→C→D→A⑦G→B→F→E→C→D→A→AnyRef→Any根据线性化计算公式得:蓝色表示起点,红色表示重复,类X不参与计算abstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}

traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}

traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}

traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}

classGextendsX{overridedefm(s:String)="G->"+s}

valx=newGwithDwithEwithFwithB

println(x.m("End"))//G->D->C->E->F->B->End所有重复项只保留最右边的,并在后面加上AnyRef和Any。684.4特质的线性化叠加计算四、特质若类G的m方法也有superX->G->D->C->E->F->B->EndabstractclassA{defm(s:String):String}

classXextendsA{defm(s:String)="X->"+s}

traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}

traitCextendsA{abstract

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论