敏捷硬件开发语言Chisel与数字系统设计 课件 第18章 抽象成员_第1页
敏捷硬件开发语言Chisel与数字系统设计 课件 第18章 抽象成员_第2页
敏捷硬件开发语言Chisel与数字系统设计 课件 第18章 抽象成员_第3页
敏捷硬件开发语言Chisel与数字系统设计 课件 第18章 抽象成员_第4页
敏捷硬件开发语言Chisel与数字系统设计 课件 第18章 抽象成员_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

18.抽象成员一、抽象成员的基本介绍二、初始化抽象val字段三、抽象类型四、细化类型五、Scala的枚举目

录2一、抽象成员的基本介绍3一、抽象成员的基本介绍抽象类和特质中的那些没有完整定义的成员。所谓没有完整定义,意思就是字段没有初始值或者函数没有函数体。1.1抽象成员的定义1.2抽象成员的四种类型traitAbstract{

typeT//抽象类型

deftransform(x:T):T//抽象方法

valinitial:T//抽象val字段

varcurrent:T//抽象var字段

}typeT=string相当于为string声明了一个别名T,此时在需要使用string的地方就可以直接使用T来代替。4一、抽象成员的基本介绍因为成员定义不充分,存在不可初始化的字段和类型,或者没有函数体的方法,所以抽象类和特质不能直接用new构造实例。那就需要继承该特质或者类的子类去实现。虽然抽象类和特质都定义了一种类型,并且它们是抽象的,但这不意味着抽象类或特质就叫抽象类型,抽象类型永远都是指的类和特质的成员,而不是类和特质本身。1.3注意事项classConcreteextendsAbstract{

typeT=String

deftransform(x:String)=x+x

valinitial="hi"

varcurrent=initial

}5二、初始化抽象val字段6二、初始化抽象val字段为超类或超特质提供参数,允许程序员在子类中提供那些在超类或者超

特质中缺失的细节。2.1抽象val字段的作用classAnonymousClassextendsRationalTrait

{

valnumerArg=1

valdenomArg=2

}

newAnonymousClasstraitRationalTrait{

valnumerArg:Int

valdenomArg:Int

}

newRationalTrait{

valnumerArg=1

valdenomArg=2

}匿名类7二、初始化抽象val字段2.2一种常见的错误在构造超特质的组件时,因为特质不能接收子类的参数,如果默认值不满足某些要求,构造就会出错。构造超特质RationalTrait组件时,会执行到这一句!!!scala>traitRationalTrait{

|valnumerArg:Int

|valdenomArg:Int

|require(denomArg!=0)

|}

definedtraitRationalTrait

scala>newRationalTrait{

|valnumerArg=1

|valdenomArg=2

|}

java.lang.IllegalArgumentException:requirementfailed

atscala.Predef$.require(Predef.scala:264)

atRationalTrait.$init$(<console>:14)

...32elided8二、初始化抽象val字段2.3预初始化字段匿名类使用预初始化字段的形式:new{定义}with超类/超特质scala>new{

|valnumerArg=1

|valdenomArg=2

|}withRationalTrait注意和不使用预初始化字段时的书写形式的区别?具名子类使用预初始化字段scala>classRationalClass(n:Int,d:Int)extends{

|valnumerArg=n

|valdenomArg=d

|}withRationalTrait

definedclassRationalClass

scala>newRationalClass(1,2)

res1:RationalClass=RationalClass@6f26e7759二、初始化抽象val字段2.4惰性的val字段-作用预初始化字段是人为地调整初始化顺序,而把val字段定义成惰性的,则可以让程序自己确定初始化顺序。在val字段前面加上关键字“lazy”,那么该字段只有首次被使用时才会进行初始化。如果是用表达式进行初始化,那就对表达式求值并保存,后续使用字段时都是复用保存的结果而不是每次都求值表达式。10二、初始化抽象val字段2.5惰性的val字段-举例scala>traitLazyRationalTrait{

|valnumerArg:Int

|valdenomArg:Int

|lazyvalnumer=numerArg/g

|lazyvaldenom=denomArg/g

|overridedeftoString=numer+"/"+denom

|privatelazyvalg={

|require(denomArg!=0)

|gcd(numerArg,denomArg)

|}

|privatedefgcd(a:Int,b:Int):Int=

|if(b==0)aelsegcd(b,a%b)

|}

definedtraitLazyRationalTraitscala>valx=2

x:Int=2

scala>newLazyRationalTrait{

|valnumerArg=1*x

|valdenomArg=2*x

|}

res0:LazyRationalTrait=1/2抽象成员惰性的val字段私有方法注意和使用预初始化字段时的书写形式不一样11三、抽象类型12三、抽象类型假设要编写一个Food类,用各种子类来表示各种食物。然后再编写一个抽象的Animal类,有一个eat方法,接收Food类型的参数。那么可能会写成如下形式:3.1问题引出scala>classFood

definedclassFood

scala>abstractclassAnimal{

|defeat(food:Food)

|}

definedclassAnimalFood类Animal类eat方法13三、抽象类型如果用不同的Animal子类来代表不同的动物,并且食物类型也会根据动物的习性发生改变。比如定义一头吃草的牛,那么可能定义如下:3.1问题引出scala>classGrassextendsFood

definedclassGrass

scala>classCowextendsAnimal{

|overridedefeat(food:Grass)={}

|}definedclassCow思考一下这种形式编译为什么会出错?14三、抽象类型3.2抽象类型的上界scala>classFooddefinedclassFood

scala>abstractclassAnimal{

|typeSuitableFood<:Food

|defeat(food:SuitableFood)

|}

definedclassAnimal

scala>classGrassextendsFooddefinedclassGrass

scala>classCowextendsAnimal{

|typeSuitableFood=Grass

|overridedefeat(food:Grass)={}

|}definedclassCow上界,<:表示SuitableFood必须是Food的某个子类定义食物为草15三、抽象类型3.2抽象类型的上界如果现在给吃草的牛喂一条鱼,那么就会发生类型错误:scala>classFishextendsFood

definedclassFish

scala>valbessy:Animal=newCow

bessy:Animal=Cow@2442f36d

scala>bessyeat(newFish)

<console>:14:error:typemismatch;

found:Fish

required:bessy.SuitableFood

bessyeat(newFish)

^16四、细化类型17四、细化类型第一种方法是定义一个食草的特质,让所有的食草动物类都混入该特质。但是这样会让食草动物与最基本的动物的关系不那么紧密。第二种方法是继承自Animal类,那么食草动物集合的元素类型就可以表示为Animal类型,但这样又可能把食肉动物或杂食动物也包含进集合。此时,就可以使用结构子类型。4.1问题引出---做一个食草动物的集合18四、细化类型当一个类继承自另一个类时,就称前者是后者的名义子类型。Scala还有一个结构子类型,表示两个类型只是有某些兼容的成员,而不是常规的那种继承来的关系。结构子类型通过细化类型来表示。例如:

4.2细化类型Animal{typeSuitableFood=Grass}valanimals:List[Animal{typeSuitableFood=Grass}]=???和Animal相比更具体和精细,属于细化类型AnimalVS19集合中的元素必须是Animal的子类型,而且食物类型必须是草。五、Scala的枚举20五、Scala的枚举Scala没有特定的语法表示枚举,而是在标准类库中提供一个枚举类:通过创建一个继承自这个类的子对象可以创建枚举。例如:5.1枚举的定义方式一对象Color和普通的单例对象一样,可以通过“Color.Red”这样的方式来访问成员,或者先用“importColor._”导入。scala.Enumerationscala>objectColorextendsEnumeration{

|valRed,Green,Blue=Value

|}

definedobjectColor21五、Scala的枚举方法Value有一个重载的版本,可以接收一个字符串参数来给枚举值关联特定的名称。例如:5.2枚举的定义方式二scala>objectDirectionextendsEnumeration{

|valNorth=Value("N")

|valEast=Value("E")

|valSouth=Value("S")

|valWest=Value("W")

|

温馨提示

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

评论

0/150

提交评论