阅读量:2
Scala OOP
前序
Scala 为纯粹OOP 1、不支持基本类型:一切皆为对象 Byte,Int,... 2、不支持静态关键字:static 3、支持类型推断【通过判断泛型的父子关系来确定泛型类的父子关系=>协变,逆变,不变】和类型预定, 动静结合
java不是纯粹的OOP的主要原因:支持基本类型,支持静态关键字。
1、类
1.1:类【主构造器】的基本构成
/* 关键字:class 创建对象:new 内含:属性(成员变量)和方法(函数=>解决问题,方法=>用于设计。因此在类中推荐写方法) 与java区别: 1、默认访问修饰符为 public,也支持 private 和 protected 2、没有构造方法,通过构造参数列表实现对象创建。因为scala类本身就是【主】构造器 */ // 主构造器 class Point(x:Int,y:Int) { // 【属性】: 构造参数名和属性不能同名 private var _x:Int = x private var _y:Int = y // 【方法】 def move(offsetX:Int,offsetY:Int): Unit = { _x += offsetX _y += offsetY } //【获取属性值】 def getX = _x def getY = _y //【修改属性值】 def setX(x:Int) = {_x=x} def setY(y:Int) = {_y=y} // 【重写】 override def toString: String = s"Point{x=${_x},y=${_y}}" } object ScalaOOP { def main(args: Array[String]): Unit = { //创建对象 val point = new Point(1, 2) //方法调用 point.move(2,4) println(point) //获取属性值 println(point.getX) //修改属性值 point.setX(21) println(point) } } ------------------------ Point{x=3,y=6} 2 Point{x=21,y=10} ------------------------
访问修饰符
修饰符 | 类(class) | 伴生对象(object) | 子类(subclass) | 同包(package) | 全局(world) |
---|---|---|---|---|---|
default(public) | Y | Y | Y | Y | Y |
protected | Y | Y | Y | N | N |
private | Y | Y | N | N | N |
1.2:辅助构造器
辅助构造器:基于主构造器的重载
class Point(x:Int,y:Int) { // 属性: 构造参数名和属性不能同名 private var _x:Int = x private var _y:Int = y //辅助构造器【必须调用主构造器,名字只能是this】 def this(x:Int) = this(x,10) // 重写方法 override def toString: String = s"Point{x=${_x},y=${_y}}" } object ScalaOOP { def main(args: Array[String]): Unit = { //创建对象 val point = new Point(2) println(point) } } ------------------------ Point{x=2,y=10} ------------------------
2、继承
class Point(x:Int,y:Int) { // 属性: 构造参数名和属性不能同名 private var _x:Int = x private var _y:Int = y // 方法 def move(offsetX:Int,offsetY:Int): Unit = { _x += offsetX _y += offsetY } //获取属性值 def getX = _x def getY = _y //修改属性值 def setX(x:Int) = {_x=x} def setY(y:Int) = {_y=y} //辅助构造器 def this(x:Int) = this(x,10) // 重写方法 override def toString: String = s"Point{x=${_x},y=${_y}}" } /** * 继承: extends & override * 目的:扩展【继承父类的主构造器】 * ColorPoint中的x,y会调用Point的x,y * colorPoint会继承父类Point的所有内容 * 注意:私有属性无法被继承 */ class ColorPoint(var x:Int,var y:Int,color:String) extends Point(x, y){ //扩展属性 private var _color:String = color //重写move方法:将x与y变为var变量【默认传入的是常量val】 override def move(offsetX: Int, offsetY: Int): Unit = { x += offsetX*2 y += offsetY*2 println(s"point moved to {${x},${y}}") } //多态 override def toString: String = s"{POINT: ${super.toString},COLOR: ${_color}}" } object ScalaOOP { def main(args: Array[String]): Unit = { val colorPoint = new ColorPoint(10, 20, "red") colorPoint.move(2,4) println(colorPoint) } } ---------------------------------------- point moved to {14,28} {POINT: Point{x=10,y=20},COLOR: red} ----------------------------------------
3、抽象类
3.1:抽象类基本知识点
抽象类: <=> 相当于java接口 1.关键字:abstract & extends & override 2.抽象类中可以有抽象方法(没有方法体的方法即抽象方法),也可以存在普通方法 3.无法实例化,需要在子类实体化后才可被使用【可以有构造器】 4.使用 abstract 关键字修饰 5.override: 5.1:子类重写父类【抽象】方法可以省略 override 关键字,但不推荐省略 5.2:子类重写父类【非抽象】方法必须写 override 关键字
3.2:抽象类详细案列讲解
//抽象类:必须用 abstract 修饰 abstract class Shape { // 抽象类中的抽象方法无需 abstract 修饰,因为【没有方法体的方法】默认为【抽象方法】 def draw():Unit // 抽象方法 // 可以包含普通方法 def show = println("this is shape")//普通方法(非抽象方法) } class Circle(radius:Float) extends Shape{ private var _radius:Float = radius //重写抽象类中的【抽象方法】【必须】,可以并推荐添加 override 关键字 override def draw(): Unit = println("you are drawing Circle...") //重写抽象类中的【非抽象方法】【可选】,必须添加 override 关键字 override def show: Unit = println(s"it is a Circle with radius of ${_radius} CM") } object ScalaOOP { def main(args: Array[String]): Unit = { val circle = new Circle(12.56f) circle.show circle.draw() } } ------------------------------------------- this is a Circle with radius of 12.56 CM you are drawing Circle... -------------------------------------------
4、单例对象
4.1:基本知识点
单列对象: 代替 Java 中的 static 关键字,作为【工具方法】来调用 1、关键字:object 2、可以包含【属性】和【方法】,且可以通过单例对象名直接调用 3、采取【惰性模式】,第一次被访问时创建 4、【无构造器,且不能 new】 5、程序入口方法main必须定义在单例对象中 6、【同一个文件】中【同名的类和单例对象】形成【绑定关系】,并称之为【伴生类和伴生对象】
4.2:单列对象
//单列对象 object Util{ //属性 val PI:Float = 3.14f var count:Int = 0 //方法 def resume = println("it is a utility object") } object ScalaOOP { def main(args: Array[String]): Unit = { println(Util.PI) Util.count += 5 println(Util.count) Util.resume } } ------------------------ 3.14 5 it is a utility object ------------------------
4.3:为什么要用单列对象?
单列对象是唯一的,具有资源共享特性【资源对于所有类的对象是共享的】。因此,类中共性的内容写在单列对象中,实现资源共享,避免重复创建问题。差异化的内容写在类中。
4.4:伴生类与伴生对象【引申】
伴生对象是一种特殊的单列对象,伴生对象属于单列对象的一种。伴生对象与伴生类之间可以自由访问。
4.4.1:【伴生对象】中可以自由访问【伴生类】中所有资源
apply和unapply讲解
package scala.cha06 // 伴生类 class Commodity(sku:String,price:Float) { private var _sku:String = sku private var _price:Float = price def getSku = _sku def getPrice = _price } // 伴生对象 object Commodity{ //apply【包裹】:实现new的简化操作【参数传入,返回对象】 def apply(sku: String, price: Float): Commodity = new Commodity(sku, price) //unapply【拆解】:【伴生对象】中可以自由访问【伴生类】中所有资源 def unapply(arg: Commodity):(String, Float) = (arg._sku,arg._price) } =================================================================================== package scala.cha06 object ScalaOOP { def main(args: Array[String]): Unit = { //不new返回单列对象apply;new返回伴生类 => 效果一致 // 自动调用 apply 完成 Commodity 对象构造 val commodity: Commodity = Commodity("草莓", 5.8f) println(commodity.getSku) println(commodity.getPrice) //unapply val t2: (String, Float) = Commodity.unapply(commodity) println(t2._1) println(t2._2) } } ----------------- 草莓 5.8 草莓 5.8 -----------------
4.4.2:【伴生类】自由访问【伴生对象】内的资源
package scala.cha06 // 伴生类 class Commodity(sku:String,price:Float) { private var _sku:String = sku private var _price:Float = price //原价 def getSku = _sku def getPrice = _price //原价 //伴生类中自由访问伴生对象的所有资源 def getSalePrice = discount(_price) //折扣价 } // 伴生对象 object Commodity{ private var _discount:Float = 1 //商品折扣 //apply:实现new的简化操作【参数传入,返回对象】 def apply(sku: String, price: Float): Commodity = new Commodity(sku, price) //自定义方法 def setDiscount(discount:Float) = {_discount = discount} //设定折扣 def discount(price:Float) = price * _discount } =================================================================================== package scala.cha06 object ScalaOOP { def main(args: Array[String]): Unit = { Commodity.setDiscount(0.88f) val commodity: Commodity = Commodity("草莓", 5.8f)//单列对象 println(commodity.getSalePrice) } } -------------- 5.104 --------------
4.5:小练习
4.5.1:题目要求
1、准备工作 假设类Book有属性title和author(多个),books是Book的列表 实现Book类,同时使用主构造器与辅助构造器 实现Book的伴生对象,使用伴生对象创建Book实例 创建books,使用List[Book]初始化5个以上Book实例 2、功能实现: 1.找出books中书名包含“xxx”的书,并打印书名 2.找出books中作者名以“xxx”打头的书,并打印书名
4.5.2:Book类与对象的构建
package scala.cha06 // 伴生类 class Book(title:String,author:Array[String]) { private var _title:String = title private var _authors:Array[String] = author //辅助构造器:实现类型转换 def this(title:String,author:String) = this(title,Array(author)) // 设计业务:解决问题前置化(在源头解决问题) //1.判断书名是否包含“xxx”的方法 def titleContains(sub:String) = _title.contains(sub) //2.判断作者名是否以“xxx”打头的方法 def authorContains(name:String) = { _authors.count(_.startsWith(name))>0 } def getTitle = _title override def toString: String = s"$title\t${_authors.mkString(",")}" } // 伴生对象 object Book{ //主构造器 def apply(title: String, author: Array[String]): Book = new Book(title, author) //辅助构造器 def apply(title: String, author: String): Book = new Book(title, author) }
4.5.3:功能实现
package scala.cha06 object ScalaOOP { def main(args: Array[String]): Unit = { val list = List( // 书名,作者名 Book("武侠:最强小保安",Array("张三","李四","王五")), Book("都市:上门赘婿",Array("阿强","洞冥福","花花")), Book("武侠:翔龙会",Array("阿庆嫂","黄世仁")), Book("都市:缘起",Array("徐世明","张丘月")), Book("武侠:小李飞刀",Array("王栋","李宏","张明")), ) //1.找出books中书名包含“xxx”的书,并打印书名 list .collect({ case book if book.titleContains("武侠") => book.getTitle }).foreach(println) println("===============") //2.找出books中作者名以“xxx”打头的书,并打印书名 list .collect({ case book if book.authorContains("李") => book.getTitle }).foreach(println) } } ------------------------ 武侠:最强小保安 武侠:翔龙会 武侠:小李飞刀 =============== 武侠:最强小保安 武侠:小李飞刀 ------------------------
5、特质
5.1:特质基本知识点
特质: <=> 【相当于java中接口】 1、关键字:trait & extends & with & override 2、包含字段、方法,亦可包含字段和方法的实现 3、类、单例对象、普通对象【都可以扩展】特质 4、不能实例化,【没有构造器】 5、单根继承extends,借助 with 实现多混入 5.1:extends与with区分: is a : extends 继承性扩展【只能用一次】 has a : implements|with 功能性扩展【可使用多次】
5.2:特质详细案例讲解
trait Animal{ //抽象属性 var name:String //普通属性 val TYPE:String = "动物" //抽象方法 def roar:Unit //普通方法 def me = s"$TYPE:$name" } //功能性trait trait BySwing{ def fly():Unit // 飞行 } trait ByFoot{ def walk():Unit // 走路 def run():Unit // 跑步 } trait ByTail{ def swim():Unit // 游泳 } /** * 1.单根继承(Animal与Cat之间是is a的关系【Animal是主要特质trait】) * 2.with实现多混入(ByFoot,ByTail与Cat之间是has a的关系【ByFoot,ByTail额外特质trait】) */ //猫 class Cat(nickName:String) extends Animal with ByFoot with ByTail { override var name: String = nickName override def roar: Unit = println(s"猫${name}喵喵...") override def walk(): Unit = println(s"猫${name}悠闲地漫步...") override def run(): Unit = println(s"猫${name}疯狂的奔跑...") override def swim(): Unit = println(s"猫${name}水里游泳...") } object TraitTest { def main(args: Array[String]): Unit = { val animal = new Cat("Tom") println(animal.name) animal.roar animal.run() animal.walk() animal.swim() } } --------------------- Tom 猫Tom喵喵... 猫Tom疯狂的奔跑... 猫Tom悠闲地漫步... ---------------------
5.2:优化特质案列
package scala.cha06 //特质trait无法使用构造器,因此用abstract来代替 abstract class Animal(brand:String){ //抽象属性 var name:String //普通属性 var _type:String = brand //抽象方法 def roar:Unit //普通方法 def me = s"${_type}:$name" } //功能性trait trait BySwing{ def fly():Unit // 飞行 } trait ByFoot{ def walk():Unit // 走路 def run():Unit // 跑步 } trait ByTail{ def swim():Unit // 游泳 } /** * 1.单根继承(Animal与Cat之间是is a的关系【Animal是主要特质trait】) * 2.with实现多混入(ByFoot与Cat之间是has a的关系【额外特质trait】) */ //猫 class Cat(nickName:String) extends Animal("猫") with ByFoot with ByTail { override var name: String = nickName override def roar: Unit = println(s"${_type}${name}喵喵...") override def walk(): Unit = println(s"${_type}${name}悠闲地漫步...") override def run(): Unit = println(s"${_type}${name}疯狂的奔跑...") override def swim(): Unit = println(s"${_type}${name}水里游泳...") } //鸟 class Bird(nickName:String) extends Animal("鸟") with BySwing with ByFoot{ override var name: String = nickName override def roar: Unit = println(s"${_type}${name}叽叽喳喳的叫...") override def fly(): Unit = println(s"${_type}${name}天空翱翔...") override def walk(): Unit = println(s"${_type}${name}闲庭信步...") override def run(): Unit = println(s"${_type}${name}蹦蹦跳跳...") } object TraitTest { def main(args: Array[String]): Unit = { val cat = new Cat("Tom") cat.roar cat.run() cat.walk() cat.swim() val bird = new Bird("Angela") bird.fly() bird.walk() bird.roar } } ------------------------ 猫Tom喵喵... 猫Tom疯狂的奔跑... 猫Tom悠闲地漫步... 猫Tom水里游泳... 鸟Angela天空翱翔... 鸟Angela闲庭信步... 鸟Angela叽叽喳喳的叫... ------------------------
6、动态混入
6.1:动态混入的解读
动态混入:未来创建对象时,将特质加进去。
通俗来讲:有些行为同一种动物会有不同表现。我们会在创建对象时,添加相对应的行为。
6.2:动态混入详细案例讲解
//特质trait无法使用构造器,因此用abstract来代替 abstract class Animal(brand:String){ //抽象属性 var name:String //普通属性 var _type:String = brand //抽象方法 def roar:Unit //普通方法 def me = s"${_type}:$name" } //功能性trait trait BySwing{ def fly():Unit // 飞行 } trait ByFoot{ def walk():Unit // 走路 def run():Unit // 跑步 } trait ByTail{ def swim():Unit // 游泳 } // 1、动态强制混入特质:只能定义一个强制混入特质,且必须位于类内首行 // self 是 this 的别名 class Fish extends Animal("鱼"){ self:ByTail=> // 强制混入特质语法 override var name: String = _ override def roar: Unit = println(s"鱼正在咕噜咕噜吐泡泡") //鱼统一相同行为 } // 同一个鱼,对于游泳这一行为有不同的表现 object TraitTest { def main(args: Array[String]): Unit = { // 1、动态强制混入特性 => ByTail行为在创建对象时是强制需要添加的 // 2、动态非强制混入特质 with,支持多混入 => 其余行为可以自行添加,此处添加了ByFoot行为 val fish1 = new Fish() with ByTail with ByFoot { // 1、动态强制混入特性 override def swim(): Unit = println(s"${_type}1快速穿梭...") // 2、动态非强制混入特质 override def walk(): Unit = println(s"${_type}1岸上散步...") override def run(): Unit = println(s"${_type}1加速追赶...") } // 3、复合类型 Fish with ByTail【可省略,如:fish1】 val fish2:Fish with ByTail = new Fish() with ByTail { // 1、动态强制混入特性 override def swim(): Unit = println(s"${_type}2水中漫游...") } fish1.swim() fish1.run() fish1.walk() fish2.swim() } } ------------------ 鱼1快速穿梭... 鱼1加速追赶... 鱼1岸上散步... 鱼2水中漫游... ------------------
7、抽象类 VS 特质
7.1:抽象类与特质的对比
一般【优先使用特质】: 1、抽象类在于多类公共属性和行为的抽象,重点在于【封装思想】,本质为类,【单继承,不支持多混入】。 2、特质(接口)在于一类事物的属性和行为标准定义,重点在于【多态思想,支持多混入】,【动态混入若需 要带参构造.只能使用抽象类】。
7.2:小练习
7.2.1:题目要求
需求说明 1.现在Book拥有电子版本,可以在多终端上播放 属性:作者author:String,书名bookName:String,类型bookType:String 内容chapters:Array[String] 方法:简介resume():Unit 2.定义Ebook特质 方法:play() 3.使Book动态混入Ebook特质,实现play()方法
7.2.2:准备工作——小说文章+书名+作者
val chapters = Array( "“春游浩荡,是年年寒食,梨花时节。白锦无纹香烂漫,玉树琼苞堆雪。静夜沉沉,浮光霭霭,冷浸溶溶月。人间天上,烂银霞照通彻。浑似姑射真人,天姿灵秀,意气殊高洁。万蕊参差谁信道,不与群芳同列。浩气清英,仙才卓荦,下土难分别。瑶台归去,洞天方看清绝。”\n\n 作这一首《无俗念》词的,乃南宋末年一位武学名家,有道之士。此人姓丘,名处机,道号长春子,名列全真七子之一,是全真教中出类拔萃的人物。《词品》评论此词道:“长春,世之所谓仙人也,而词之清拔如此”。这首词诵的似是梨花,其实词中真意却是赞誉一位身穿白衣的美貌少女,说她“浑似姑射真人,天姿灵秀,意气殊高洁”,又说她“浩气清英,仙才卓荦”,“不与群芳同列”。词中所颂这美女,乃古墓派传人小龙女。她一生爱穿白衣,当真如风拂玉树,雪裹琼苞,兼之生性清冷,实当得起“冷浸溶溶月”的形容,以“无俗念”三字赠之,可说十分贴切。长春子丘处机和她在终南山上比邻而居,当年一见,便写下这首词来。\n\n 这时丘处机逝世已久,小龙女也已嫁与神雕大侠杨过为妻。在河南少室山山道之上,却另有一个少女,正在低低念诵此词。这少女十**岁年纪,身穿淡黄衣衫,骑着一头青驴,正沿山道缓缓而上,心中默想:“也只有龙姊姊这样的人物,才配得上他。”这一个“他”字,指的自然是神雕大侠杨过了。她也不拉缰绳,任由那青驴信步而行,一路上山。过了良久,她又低声吟道:“欢乐趣,离别苦,就中更有痴儿女。君应有语,渺万里层云,千山暮雪,只影向谁去?”", "她腰悬短剑,脸上颇有风尘之色,显是远游已久;韶华如花,正当喜乐无忧之年,可是容色间却隐隐有懊闷意,似是愁思袭人,眉间心上,无计回避。\n\n 这少女姓郭,单名一个襄字,乃大侠郭靖和女侠黄蓉的次女,有个外号叫做“小东邪”。她一驴一剑,只身漫游,原想排遣心中愁闷,岂知酒入愁肠固然愁上加愁,而名山独游,一般的也是愁闷徒增。河南少室山山势颇陡,山道却是一长列宽大的石级,规模宏伟,工程着实不小,那是唐朝高宗为临幸少林寺而开凿,共长八里。郭襄骑着青驴委折而上,只见对面山上五道瀑布飞珠溅玉,奔泻而下,再俯视群山,已如蚁蛭。顺着山道转过一个弯,遥见黄墙碧瓦,好大一座寺院。\n\n 她望着连绵屋宇出了一会神,心想:“少林寺向为天下武学之源,但华山两次论剑,怎地五绝之中并无少林寺高僧?难道寺中和尚自忖没有把握,生怕堕了威名,索性便不去与会?又难道众僧侣修为精湛,名心尽去,武功虽高,却不去和旁人争强赌胜?”她下了青驴,缓步走向寺前,只见树木森森,荫着一片碑林。石碑大半已经毁破,字迹模糊,不知写着些甚么。心想:“便是刻凿在石碑上的字,年深月久之后也须磨灭,如何刻在我心上的,却是时日越久反而越加清晰?”瞥眼只见一块大碑上刻着唐太宗赐少林寺寺僧的御札,嘉许少林寺僧立功平乱。碑文中说唐太宗为秦王时,带兵讨伐王世充,少林寺和尚投军立功,最著者共一十三人。其中只昙宗一僧受封为大将军,其余十二僧不愿为官,唐太宗各赐紫罗袈裟一袭。她神驰想象:“当隋唐之际,少林寺武功便已名驰天下,数百年来精益求精,这寺中卧虎藏龙,不知有多少好手。”郭襄自和杨过、小龙女夫妇在华山绝顶分手后,三年来没得到他二人半点音讯。她心中长自记挂,于是禀明父母,说要出来游山玩水,实则是打听杨过的消息,她倒也不一定要和他夫妇会面,只须听到一些杨过如何在江湖上行侠的讯息,也便心满意足了。偏生一别之后,他夫妇从此便不在江湖上露面,不知到了何处隐居,郭襄自北而南,又从东至西,几乎踏遍了大半个中原,始终没听到有人说起神雕大侠杨过的近讯。这一日她到了河南,想起少林寺中有一位僧人无色禅师是杨过的好友,自己十六岁生日之时,无色瞧在杨过的面上,曾托人送来一件礼物,虽然从未和他见过面,但不妨去问他一问,说不定他会知道杨过的踪迹,这才上少林寺来。正出神间,忽听得碑林旁树丛后传出一阵铁链当啷之声,一人诵念佛经:“是时药叉共王立要,即于无量百千万亿大众之中,说胜妙伽他曰:由爱故生忧,由爱故生怖;若离于爱者,无忧亦无怖……”郭襄听了这四句偈言,不由得痴了,心中默默念道:“由爱故生忧,由爱故生怖;若离于爱者,无忧亦无怖。”只听得铁链拖地和念佛之声渐渐远去。郭襄低声道:“我要问他,如何才能离于爱,如何能无忧无怖?”随手将驴缰在树上一绕,拨开树丛,追了过去。只见树后是一条上山的小径,一个僧人挑了一对大桶,正缓缓往山上走去。郭襄快步跟上,奔到距那僧人七八丈处,不由得吃了一惊,只见那僧人挑的是一对大铁桶,比之寻常水桶大了两倍有余,那僧人颈中、手上、脚上,更绕满了粗大的铁链,行走时铁链拖地,不停发出声响。这对大铁桶本身只怕便有二百来斤,桶中装满了水,重量更是惊人。郭襄叫道:“大和尚,请留步,小女子有句话请教。”", "那僧人回过头来,两人相对,都是一愕。原来这僧人便是觉远,三年以前,两人在华山绝顶曾有一面之缘。郭襄知他虽然生性迂腐,但内功深湛,不在当世任何高手之下,便道:“我道是谁,原来是觉远大师。你如何变成了这等模样?”觉远点了点头,微微一笑,合十行礼,并不答话,转身便走。郭襄叫道:“觉远大师,你不认得我了么?我是郭襄啊。”觉远又是回首一笑,点了点头,这次更不停步。郭襄又道:“是谁用铁链绑住了你?如何这般虐待你?”觉远左掌伸到脑后摇了几摇,示意她不必再问。\n\n 郭襄见了这等怪事,如何肯不弄个明白?当下飞步追赶,想抢在他面前拦住,岂知觉远虽然全身带了铁链,又挑着一对大铁桶,但郭襄快步追赶,始终抢不到他身前。郭襄童心大起,展开家传轻功,双足一点,身子飞起,伸手往铁桶边上抓去,眼见这一下必能抓中。不料落手时终究还是差了两寸。郭襄叫道:“大和尚,这般好本事,我非追上你不可。”但见觉远不疾不徐的迈步而行,铁链声当啷当啷有如乐音,越走越高,直至后山。郭襄直奔得气喘渐急,但仍和他相距丈余,不由得心中佩服:“爹爹妈妈在华山之上,便说这位大和尚武功极高,当时我还不大相信,今日一试,才知爹妈的话果然不错。”只见觉远转身走到一间小屋之后,将铁桶中的两桶水都倒进了一口井中。郭襄大奇,叫道:“大和尚,你莫非疯了,挑水倒在井中干么?”觉远神色平和,只摇了摇头。郭襄忽有所悟,笑道:“啊,你是在练一门高深的武功。”觉远又摇了摇头。郭襄心中着恼,说道:“我刚才明明听得你在念经,又不是哑了,怎地不答我的话?”觉远合十行礼,脸上似有歉意,一言不发,挑了铁桶便下山去。郭襄探头井口向下望去,只见井水清澈,也无特异之处,怔怔望着觉远的背影,心中满是疑窦。她适才一阵追赶,微感心浮气躁,于是坐在井栏圈上,观看四下风景,这时置身处已高于少林寺所有屋宇,但见少室山层崖刺天,横若列屏,崖下风烟飘渺,寺中钟声随风送上,令人一洗烦俗之气。郭襄心想:“这和尚的弟子不知在哪里,和尚既不肯说,我去问那个少年便了。”当下信步落山,想去找觉远的弟子张君宝来问。走了一程,忽听得铁链声响,觉远又挑了水上来。郭襄闪身躲在树后,心想:“我暗中瞧瞧他到底在捣甚么鬼。”铁链声渐近,只见觉远仍是挑着那对铁桶,手中却拿着一本书,全神贯注的轻声诵读。郭襄待他走到身边,猛地里跃出,叫道:“大和尚,你看甚么书?”\n\n 觉远失声叫道:“啊哟,吓了我一跳,原来是你。”郭襄笑道:“你装哑巴装不成了罢,怎么说话了?”觉远微有惊色,向左右一望,摇了摇手。郭襄道:“你怕甚么?”觉远还未回答,突然树林中转出两个灰衣僧人,一高一矮。那瘦长僧人喝道:“觉远,不守戒法,擅自开口说话,何况又和庙外生人对答,更何况又和年轻女子说话?这便见戒律堂首座去。”觉远垂头丧气,点了点头,跟在那两个僧人之后。郭襄大为惊怒,喝道:“天下还有不许人说话的规矩么?我识得这位大师,我自跟他说话,干你们何事?”那瘦长僧人白眼一翻,说道:“千年以来,少林寺向不许女流擅入。姑娘请下山去罢,免得自讨没趣。”郭襄心中更怒,说道:“女流便怎样?难道女子便不是人?你们干么难为这位觉远大师?既用铁链捆绑他,又不许他说话?”那僧人冷冷的道:“本寺之事,便是皇帝也管不着。何劳姑娘多问?”", "郭襄怒道:“这位大师是忠厚老实的好人,你们欺他仁善,便这般折磨于他,哼哼,天鸣禅师呢?无色和尚、无相和尚在哪里?你去叫他们出来,我倒要问问这个道理。”两个僧人听了都是一惊。天鸣禅师是少林寺方丈,无色禅师是本寺罗汉堂首座,无相禅师是达摩堂首座,三人位望尊崇,寺中僧侣向来只称“老方丈”、“罗汉堂座师”、“达摩堂座师”,从来不敢提及法名,岂知一个年轻女子竟敢上山来大呼小叫,直斥其名。那两名僧人都是戒律堂首座的弟子,奉了座师之命,监视觉远,这时听郭襄言语莽撞,那瘦长僧人喝道:“女施主再在佛门清净之地滋扰,莫怪小僧无礼。”\n\n 郭襄道:“难道我还怕了你这和尚?你快快把觉远大师身上的铁链除去,那便算了,否则我找天鸣老和尚算帐去。”那矮僧听郭襄出言无状,又见她腰悬短剑,沉着嗓子道:“你把兵刃留下,我们也不来跟你一般见识,快下山去罢。”郭襄摘下短剑,双手托起,冷笑道:“好罢,谨遵台命。”那矮僧自幼在少林寺出家,一向听师伯、师叔、师兄们说少林寺是天下武学的总源,又听说不论名望多大、本领多强的武林高手,从不敢携带兵刃走进少林寺出门。这年轻姑娘虽然未入寺门,但已在少林寺范围之内,只道她真是怕了,乖乖交出短剑,于是伸手便去接剑。他手指刚碰到剑鞘,突然间手臂剧震,如中电掣,但觉一股强力从短剑上传了过来,推得他向后急仰,立足不定,登时摔倒。他身在斜坡之上,一经摔倒,便骨碌碌的向下滚了数丈,好容易硬生生的撑住,这才不再滚动。那瘦长僧人又惊又怒,喝道:“你吃了狮子心豹子胆,竟到少林寺撒野来啦!”转过身来,踏上一步,右手一拳击出,左掌跟着在右拳上一搭,变成双掌下劈,正是“闯少林”第二十八势“翻身劈击”。郭襄握住剑柄,连剑带鞘向他肩头砸去。那僧人沉肩回掌,来抓剑鞘。觉远在旁瞧得惶急,大叫:“别动手,别动手!有话好说。”便在此时,那僧人右手已抓住剑鞘,正却运劲里夺,猛觉手心一震,双臂隐隐酸麻,只叫得一声:“不好!”郭襄左腿横扫,已将他踢下坡去。他所受的这一招比那矮僧重得多,一路翻滚,头脸上擦出不少鲜血,这才停住。郭襄心道:“我上少林寺来是打听大哥哥的讯息,平白无端的跟他们动手,当真好没来由。”眼见觉远愁眉苦脸的站在一旁,当即抽出短剑,便往他手脚上的铁链削去。这短剑虽非稀世奇珍,却也是极锋锐的利器,只听得当啷啷几声响,铁链断了三条。觉远连呼:“使不得,使不得!”郭襄道:“甚么使不得?”指着正向寺内奔去的高矮二僧说道:“这两个恶和尚定是奔去报讯,咱们快走。你那个姓张的小徒儿呢?带了他一起走罢!”觉远只是摇手。忽听得身后一人说道:“多谢姑娘关怀,小的在这儿。”\n\n 郭襄回过头来,只见身后站着个十六七岁的少年,粗眉大眼,身材魁伟,脸上却犹带稚气,正是三年前曾在华山之巅会过的张君宝。比之当日,他身形已高了许多,但容貌无甚改变。郭襄大喜,说道:“这里的恶和尚欺侮你师父,咱们走罢。”张君宝摇头道:“没有谁欺侮我师父啊。”郭襄指着觉远道:“那两个恶和尚用铁链锁着你师父,连一句话也不许他说,还不是欺侮?”觉远苦笑摇头,指了指山下,示意郭襄及早脱身,免惹事端。郭襄明知少林寺中武功胜过她的人不计其数,但既见了眼前的不平之事,决不能便此撒手不顾;可是却又担心寺中好手出来截拦,当下一手拉了觉远,一手拉了张君宝,顿足道:“快走快走,有甚么事,下山去慢慢说不好么?”两人只是不动。忽见山坡下寺院边门中冲出七八名僧人,手提齐眉木棍,吆喝道:“哪里来的野姑娘,胆敢来少林寺撒野?”张君宝提起嗓子叫道:“各位师兄不得无礼,这位是……”郭襄忙道:“别说我名字。”她想今日的祸事看来闯得不小,说不定闹下去会不可收拾,可别牵累到爹爹妈妈,又补上一句:“咱们翻山走罢!千万别提我爹爹妈妈和朋友的姓名。”只听得背后山顶上吆喝声响,又涌出七八名僧人来。郭襄见前后都出现了僧人,秀眉深蹙,急道:“你们两个婆婆妈妈,没点男子汉气概!到底走不走?”张君宝道:“师父,郭姑娘一片好意……”", "便在此时,下面边门中又窜出四名黄衣僧人,飕飕飕的奔上坡来,手中都没兵器,但身法迅捷,衣襟带风,武功颇为了得。郭襄见这般情势,便想单独脱身亦已不能,索性凝气卓立,静观其变。当先一名僧人奔到离她四丈之处,朗声说道:“罗汉堂首座尊师传谕:着来人放下兵刃,在山下一苇亭中陈明详情,听由法谕。”\n\n 郭襄冷笑道:“少林寺的大和尚官派十足,官腔打得倒好听。请问各位大和尚做的是大宋皇帝的官儿呢,还是做蒙古皇帝的官?”这时淮水以北,大宋国土均已沦陷,少林寺所在之地自也早该归蒙古管,只是蒙古大军连年进攻襄阳不克,忙于调兵遣将,也无余力来理会丛林寺观的事,因此少林寺一如其旧,与前并无不同。那僧人听郭襄讥刺之言甚是厉害,不由得脸上一红,心中也觉对外人下令传谕有些不妥,合十说道:“不知女施主何事光临敝寺,且请放下兵刃,赴山下一苇亭中奉茶说话。”郭襄听他语转和缓,便想乘此收蓬,说道:“你们不让我进寺,我便希罕了?哼,难道少林寺中有宝,我见一见便沾了光么?”向张君宝使个眼色,低声道:“到底走不走?”张君宝摇摇头,嘴角向觉远一努,意思说是要服侍师父。郭襄朗声道:“好,那我不管啦,我走了。”拔步便下坡去。第一名黄衣僧侧身让开。第二名和第三名黄衣僧却同时伸手一拦,齐声道:“且慢,放下了兵刃。”郭襄眉毛一扬,手按剑柄。第一名僧人道:“我们也不敢留着女施主的兵刃。女施主一到山下,我们立即将宝剑送上,这是少林寺千年来的规矩,还请包涵。”郭襄听他言语有礼,心下踌躇:“倘若不留短剑,势必有场争斗,我孤身一人,如何是阖寺僧众的敌手?但若留下短剑,岂不将外公、爹爹、妈妈、大哥哥、龙姊姊的面子一古脑儿都丢得干净?”她一时沉吟未决,蓦地里眼前黄影晃动,一人喝道:“到少林寺来既带剑,又伤人,世上焉有是理?”跟着劲风飒然,五只手指往剑鞘上抓下来。这僧人若不贸然出手,郭襄一番迟疑之后,多半便会将短剑留下。她和乃姊郭芙的性子大不相同,虽然豪爽,却不鲁莽,眼前处境既极度不利,便会暂忍一时之气,日后再去和外公、爹妈商量,回头找这场子,但对方突然逞强,岂能眼睁睁的让他将剑夺去?那僧人的擒拿手法既狠且巧,一抓住剑鞘,心想郭襄定会向里回夺,一个和尚跟一个年轻女子拉拉扯扯,大是不雅,当下运劲向左斜推,跟着抓而向右。郭襄被他这么一推一抓,果然已拿不牢剑鞘,当即握住剑柄,刷的一声,寒光出匣。那僧人右手将剑鞘夺了过去,左手却有两根手指被短剑顺势割断,剧痛之下,抛下剑鞘,往旁退开。\n\n 众僧人见同门受伤,无不惊怒,挥杖舞棍,一齐攻来。郭襄心想:“一不做二不休,反正今日已不能善罢。”当下使出家传的“落英剑法”,便往山下冲去。众僧人排成三列,仰面挡住。那“落英剑法”乃黄药师从“落英掌法”的路子中演化来,虽不若“玉箫剑法”的精妙,却也是桃花岛的一绝,但见青光激荡,剑花点点,便似落英缤纷,四散而下,霎时间僧人中又有两人受伤。但背后数名僧人跟着抢到,居高临下的夹攻。按理郭襄早已抵挡不住,只是少林僧众慈悲为本,不愿伤她性命,所出招数都非杀手,只求将她打倒,训诫一番,扣下兵刃,将她逐下山去。可是郭襄剑光错落,却也不易攻近身去。众僧初时只道一个妙龄女郎,还不轻易打发?待见她剑法精奇,始知她若非名门之女,便是名师之徒,多半得罪不得,出招时更有分寸,一面急报罗汉堂首座无色禅师。正斗之间,一个身材高瘦老年僧人缓步走近,双手笼在袖中,微笑观斗。两名僧人走到他身前,低声禀告了几句。郭襄已斗得气喘吁吁,剑法凌乱,大声喝道:“说甚么天下武学之源,原来是十多个和尚一拥而上,倚多为胜。”那老僧便是罗汉堂首座无色禅师,听她这么说,便道:“各人住手!”众僧人立时罢手跃开。无色禅师道:“姑娘贵姓,令尊和令师是谁?光临少林寺,不知有何贵干?”郭襄心道:“我爹娘的姓名不能告诉你。我到少林寺来是为了打听大哥哥的讯息,那也不能当众述说。眼下已闹成这等模样,日后爹娘和大哥哥知道了定要怪我,不如悄悄的溜了罢。”说道:“我的姓名不能跟你说,我不过见山上风景优美,这便上来游览玩耍。原来少林寺比皇宫内院还要厉害,动不动便要扣人家兵刃。请问大师,我进了贵寺的山门没有?当日达摩祖师传下武艺,想来也不过教众僧侣强身健体,便于精进修为,想不到少林寺名头越大,武功越高,恃众逞强的名头也越来越响。好,你们要扣我兵刃,这便留下,除非将我杀了,否则今日之事江湖上不会无人知晓。”她本来伶牙俐齿,这件事也并非全是她的过错,一席话只将无色禅师说得哑口无言。郭襄鉴貌辨色,心想:“这番胡闹我固怕人知晓,看来少林寺更加不愿张扬。十多个和尚围斗一个年轻姑娘,说出去有甚么好听?”当下哼的一声,将短剑往地下一掷,举步便行。" ) val book = EBook("倚天屠龙记","张天爱","武侠小说")
7.2.3:具体展示
EBook
package scala.cha06 import java.util.regex.{Matcher, Pattern} import scala.collection.mutable.ArrayBuffer class Book(title:String,author:Array[String]) { val _title:String = title val _authors:Array[String] = author //辅助构造器:实现类型转换 def this(title:String,author:String) = this(title,Array(author)) // 设计业务:解决问题前置化(在源头解决问题) //1.判断书名是否包含“xxx”的方法 def titleContains(sub:String) = _title.contains(sub) //2.判断作者名是否以“xxx”打头的方法 def authorContains(name:String) = { _authors.count(_.startsWith(name))>0 } def getTitle = _title override def toString: String = s"$title\t${_authors.mkString(",")}" } object Book{ //主构造器 def apply(title: String, author: Array[String]): Book = new Book(title, author) //辅助构造器 def apply(title: String, author: String): Book = new Book(title, author) } //================================================= trait EAction{ //看某一个章节 def play(chapterNo:Int):Unit //判断是否继续观看并展示章节内容 def play() } class EBook(title:String,author:Array[String],bookType:String) extends Book(title,author) with EAction { val _bookType:String = bookType //书类型 val _chapters:ArrayBuffer[String] = ArrayBuffer() //章节数 def this(title:String,author:String,bookType:String) = this(title,Array(author),bookType) def chapterCount = _chapters.size def resume:Unit = println(s"类型:${_bookType} ,标题:${_title},作者:${_authors.mkString("、")},章节数:${_chapters.size}") //将章节加进来 def addChapter(chapter:String):Unit = { _chapters.append(chapter) } //输出文章内容(本质是java,可在java中运行验证再复制于此) private def showChapter(chapter:String): Unit ={ val patLine: Pattern = Pattern.compile("([^\n]{1,30})")//一行30个 val matcher: Matcher = patLine.matcher(chapter) while (matcher.find){ System.out.println(matcher.group(1)) } } override def play(chapterNo: Int): Unit = { if(chapterNo>=1 && chapterNo<=_chapters.size){ showChapter(_chapters(chapterNo-1)) }else{ println("无此章节") } } override def play(): Unit = { import scala.util.control.Breaks._ //控制 import scala.io.StdIn._ //控制台输入 //给个选择,跳出循环 breakable({ var chapterNo = 1 //当前读取的章节数 while (chapterNo<=chapterCount){ play(chapterNo) //跳转至第chapterNo章节,展示当前章节内容 print("是否继续读取:") //readLine():读取控制台输入内容,用于判断是否继续读取 if(!readLine().matches("y|Y")){ break() //跳出breakable结构 } chapterNo += 1 } }) } } object EBook{ //简化构造方式 def apply(title: String, author: String, bookType: String): EBook = new EBook(title, author, bookType) }
测试结果
package scala.cha06 object ScalaOOP { def main(args: Array[String]): Unit = { val chapters = Array( "“春游浩荡,是年年寒食,梨花时节。白锦无纹香烂漫,玉树琼苞堆雪。静夜沉沉,浮光霭霭,冷浸溶溶月。人间天上,烂银霞照通彻。浑似姑射真人,天姿灵秀,意气殊高洁。万蕊参差谁信道,不与群芳同列。浩气清英,仙才卓荦,下土难分别。瑶台归去,洞天方看清绝。”\n\n 作这一首《无俗念》词的,乃南宋末年一位武学名家,有道之士。此人姓丘,名处机,道号长春子,名列全真七子之一,是全真教中出类拔萃的人物。《词品》评论此词道:“长春,世之所谓仙人也,而词之清拔如此”。这首词诵的似是梨花,其实词中真意却是赞誉一位身穿白衣的美貌少女,说她“浑似姑射真人,天姿灵秀,意气殊高洁”,又说她“浩气清英,仙才卓荦”,“不与群芳同列”。词中所颂这美女,乃古墓派传人小龙女。她一生爱穿白衣,当真如风拂玉树,雪裹琼苞,兼之生性清冷,实当得起“冷浸溶溶月”的形容,以“无俗念”三字赠之,可说十分贴切。长春子丘处机和她在终南山上比邻而居,当年一见,便写下这首词来。\n\n 这时丘处机逝世已久,小龙女也已嫁与神雕大侠杨过为妻。在河南少室山山道之上,却另有一个少女,正在低低念诵此词。这少女十**岁年纪,身穿淡黄衣衫,骑着一头青驴,正沿山道缓缓而上,心中默想:“也只有龙姊姊这样的人物,才配得上他。”这一个“他”字,指的自然是神雕大侠杨过了。她也不拉缰绳,任由那青驴信步而行,一路上山。过了良久,她又低声吟道:“欢乐趣,离别苦,就中更有痴儿女。君应有语,渺万里层云,千山暮雪,只影向谁去?”", "她腰悬短剑,脸上颇有风尘之色,显是远游已久;韶华如花,正当喜乐无忧之年,可是容色间却隐隐有懊闷意,似是愁思袭人,眉间心上,无计回避。\n\n 这少女姓郭,单名一个襄字,乃大侠郭靖和女侠黄蓉的次女,有个外号叫做“小东邪”。她一驴一剑,只身漫游,原想排遣心中愁闷,岂知酒入愁肠固然愁上加愁,而名山独游,一般的也是愁闷徒增。河南少室山山势颇陡,山道却是一长列宽大的石级,规模宏伟,工程着实不小,那是唐朝高宗为临幸少林寺而开凿,共长八里。郭襄骑着青驴委折而上,只见对面山上五道瀑布飞珠溅玉,奔泻而下,再俯视群山,已如蚁蛭。顺着山道转过一个弯,遥见黄墙碧瓦,好大一座寺院。\n\n 她望着连绵屋宇出了一会神,心想:“少林寺向为天下武学之源,但华山两次论剑,怎地五绝之中并无少林寺高僧?难道寺中和尚自忖没有把握,生怕堕了威名,索性便不去与会?又难道众僧侣修为精湛,名心尽去,武功虽高,却不去和旁人争强赌胜?”她下了青驴,缓步走向寺前,只见树木森森,荫着一片碑林。石碑大半已经毁破,字迹模糊,不知写着些甚么。心想:“便是刻凿在石碑上的字,年深月久之后也须磨灭,如何刻在我心上的,却是时日越久反而越加清晰?”瞥眼只见一块大碑上刻着唐太宗赐少林寺寺僧的御札,嘉许少林寺僧立功平乱。碑文中说唐太宗为秦王时,带兵讨伐王世充,少林寺和尚投军立功,最著者共一十三人。其中只昙宗一僧受封为大将军,其余十二僧不愿为官,唐太宗各赐紫罗袈裟一袭。她神驰想象:“当隋唐之际,少林寺武功便已名驰天下,数百年来精益求精,这寺中卧虎藏龙,不知有多少好手。”郭襄自和杨过、小龙女夫妇在华山绝顶分手后,三年来没得到他二人半点音讯。她心中长自记挂,于是禀明父母,说要出来游山玩水,实则是打听杨过的消息,她倒也不一定要和他夫妇会面,只须听到一些杨过如何在江湖上行侠的讯息,也便心满意足了。偏生一别之后,他夫妇从此便不在江湖上露面,不知到了何处隐居,郭襄自北而南,又从东至西,几乎踏遍了大半个中原,始终没听到有人说起神雕大侠杨过的近讯。这一日她到了河南,想起少林寺中有一位僧人无色禅师是杨过的好友,自己十六岁生日之时,无色瞧在杨过的面上,曾托人送来一件礼物,虽然从未和他见过面,但不妨去问他一问,说不定他会知道杨过的踪迹,这才上少林寺来。正出神间,忽听得碑林旁树丛后传出一阵铁链当啷之声,一人诵念佛经:“是时药叉共王立要,即于无量百千万亿大众之中,说胜妙伽他曰:由爱故生忧,由爱故生怖;若离于爱者,无忧亦无怖……”郭襄听了这四句偈言,不由得痴了,心中默默念道:“由爱故生忧,由爱故生怖;若离于爱者,无忧亦无怖。”只听得铁链拖地和念佛之声渐渐远去。郭襄低声道:“我要问他,如何才能离于爱,如何能无忧无怖?”随手将驴缰在树上一绕,拨开树丛,追了过去。只见树后是一条上山的小径,一个僧人挑了一对大桶,正缓缓往山上走去。郭襄快步跟上,奔到距那僧人七八丈处,不由得吃了一惊,只见那僧人挑的是一对大铁桶,比之寻常水桶大了两倍有余,那僧人颈中、手上、脚上,更绕满了粗大的铁链,行走时铁链拖地,不停发出声响。这对大铁桶本身只怕便有二百来斤,桶中装满了水,重量更是惊人。郭襄叫道:“大和尚,请留步,小女子有句话请教。”", "那僧人回过头来,两人相对,都是一愕。原来这僧人便是觉远,三年以前,两人在华山绝顶曾有一面之缘。郭襄知他虽然生性迂腐,但内功深湛,不在当世任何高手之下,便道:“我道是谁,原来是觉远大师。你如何变成了这等模样?”觉远点了点头,微微一笑,合十行礼,并不答话,转身便走。郭襄叫道:“觉远大师,你不认得我了么?我是郭襄啊。”觉远又是回首一笑,点了点头,这次更不停步。郭襄又道:“是谁用铁链绑住了你?如何这般虐待你?”觉远左掌伸到脑后摇了几摇,示意她不必再问。\n\n 郭襄见了这等怪事,如何肯不弄个明白?当下飞步追赶,想抢在他面前拦住,岂知觉远虽然全身带了铁链,又挑着一对大铁桶,但郭襄快步追赶,始终抢不到他身前。郭襄童心大起,展开家传轻功,双足一点,身子飞起,伸手往铁桶边上抓去,眼见这一下必能抓中。不料落手时终究还是差了两寸。郭襄叫道:“大和尚,这般好本事,我非追上你不可。”但见觉远不疾不徐的迈步而行,铁链声当啷当啷有如乐音,越走越高,直至后山。郭襄直奔得气喘渐急,但仍和他相距丈余,不由得心中佩服:“爹爹妈妈在华山之上,便说这位大和尚武功极高,当时我还不大相信,今日一试,才知爹妈的话果然不错。”只见觉远转身走到一间小屋之后,将铁桶中的两桶水都倒进了一口井中。郭襄大奇,叫道:“大和尚,你莫非疯了,挑水倒在井中干么?”觉远神色平和,只摇了摇头。郭襄忽有所悟,笑道:“啊,你是在练一门高深的武功。”觉远又摇了摇头。郭襄心中着恼,说道:“我刚才明明听得你在念经,又不是哑了,怎地不答我的话?”觉远合十行礼,脸上似有歉意,一言不发,挑了铁桶便下山去。郭襄探头井口向下望去,只见井水清澈,也无特异之处,怔怔望着觉远的背影,心中满是疑窦。她适才一阵追赶,微感心浮气躁,于是坐在井栏圈上,观看四下风景,这时置身处已高于少林寺所有屋宇,但见少室山层崖刺天,横若列屏,崖下风烟飘渺,寺中钟声随风送上,令人一洗烦俗之气。郭襄心想:“这和尚的弟子不知在哪里,和尚既不肯说,我去问那个少年便了。”当下信步落山,想去找觉远的弟子张君宝来问。走了一程,忽听得铁链声响,觉远又挑了水上来。郭襄闪身躲在树后,心想:“我暗中瞧瞧他到底在捣甚么鬼。”铁链声渐近,只见觉远仍是挑着那对铁桶,手中却拿着一本书,全神贯注的轻声诵读。郭襄待他走到身边,猛地里跃出,叫道:“大和尚,你看甚么书?”\n\n 觉远失声叫道:“啊哟,吓了我一跳,原来是你。”郭襄笑道:“你装哑巴装不成了罢,怎么说话了?”觉远微有惊色,向左右一望,摇了摇手。郭襄道:“你怕甚么?”觉远还未回答,突然树林中转出两个灰衣僧人,一高一矮。那瘦长僧人喝道:“觉远,不守戒法,擅自开口说话,何况又和庙外生人对答,更何况又和年轻女子说话?这便见戒律堂首座去。”觉远垂头丧气,点了点头,跟在那两个僧人之后。郭襄大为惊怒,喝道:“天下还有不许人说话的规矩么?我识得这位大师,我自跟他说话,干你们何事?”那瘦长僧人白眼一翻,说道:“千年以来,少林寺向不许女流擅入。姑娘请下山去罢,免得自讨没趣。”郭襄心中更怒,说道:“女流便怎样?难道女子便不是人?你们干么难为这位觉远大师?既用铁链捆绑他,又不许他说话?”那僧人冷冷的道:“本寺之事,便是皇帝也管不着。何劳姑娘多问?”", "郭襄怒道:“这位大师是忠厚老实的好人,你们欺他仁善,便这般折磨于他,哼哼,天鸣禅师呢?无色和尚、无相和尚在哪里?你去叫他们出来,我倒要问问这个道理。”两个僧人听了都是一惊。天鸣禅师是少林寺方丈,无色禅师是本寺罗汉堂首座,无相禅师是达摩堂首座,三人位望尊崇,寺中僧侣向来只称“老方丈”、“罗汉堂座师”、“达摩堂座师”,从来不敢提及法名,岂知一个年轻女子竟敢上山来大呼小叫,直斥其名。那两名僧人都是戒律堂首座的弟子,奉了座师之命,监视觉远,这时听郭襄言语莽撞,那瘦长僧人喝道:“女施主再在佛门清净之地滋扰,莫怪小僧无礼。”\n\n 郭襄道:“难道我还怕了你这和尚?你快快把觉远大师身上的铁链除去,那便算了,否则我找天鸣老和尚算帐去。”那矮僧听郭襄出言无状,又见她腰悬短剑,沉着嗓子道:“你把兵刃留下,我们也不来跟你一般见识,快下山去罢。”郭襄摘下短剑,双手托起,冷笑道:“好罢,谨遵台命。”那矮僧自幼在少林寺出家,一向听师伯、师叔、师兄们说少林寺是天下武学的总源,又听说不论名望多大、本领多强的武林高手,从不敢携带兵刃走进少林寺出门。这年轻姑娘虽然未入寺门,但已在少林寺范围之内,只道她真是怕了,乖乖交出短剑,于是伸手便去接剑。他手指刚碰到剑鞘,突然间手臂剧震,如中电掣,但觉一股强力从短剑上传了过来,推得他向后急仰,立足不定,登时摔倒。他身在斜坡之上,一经摔倒,便骨碌碌的向下滚了数丈,好容易硬生生的撑住,这才不再滚动。那瘦长僧人又惊又怒,喝道:“你吃了狮子心豹子胆,竟到少林寺撒野来啦!”转过身来,踏上一步,右手一拳击出,左掌跟着在右拳上一搭,变成双掌下劈,正是“闯少林”第二十八势“翻身劈击”。郭襄握住剑柄,连剑带鞘向他肩头砸去。那僧人沉肩回掌,来抓剑鞘。觉远在旁瞧得惶急,大叫:“别动手,别动手!有话好说。”便在此时,那僧人右手已抓住剑鞘,正却运劲里夺,猛觉手心一震,双臂隐隐酸麻,只叫得一声:“不好!”郭襄左腿横扫,已将他踢下坡去。他所受的这一招比那矮僧重得多,一路翻滚,头脸上擦出不少鲜血,这才停住。郭襄心道:“我上少林寺来是打听大哥哥的讯息,平白无端的跟他们动手,当真好没来由。”眼见觉远愁眉苦脸的站在一旁,当即抽出短剑,便往他手脚上的铁链削去。这短剑虽非稀世奇珍,却也是极锋锐的利器,只听得当啷啷几声响,铁链断了三条。觉远连呼:“使不得,使不得!”郭襄道:“甚么使不得?”指着正向寺内奔去的高矮二僧说道:“这两个恶和尚定是奔去报讯,咱们快走。你那个姓张的小徒儿呢?带了他一起走罢!”觉远只是摇手。忽听得身后一人说道:“多谢姑娘关怀,小的在这儿。”\n\n 郭襄回过头来,只见身后站着个十六七岁的少年,粗眉大眼,身材魁伟,脸上却犹带稚气,正是三年前曾在华山之巅会过的张君宝。比之当日,他身形已高了许多,但容貌无甚改变。郭襄大喜,说道:“这里的恶和尚欺侮你师父,咱们走罢。”张君宝摇头道:“没有谁欺侮我师父啊。”郭襄指着觉远道:“那两个恶和尚用铁链锁着你师父,连一句话也不许他说,还不是欺侮?”觉远苦笑摇头,指了指山下,示意郭襄及早脱身,免惹事端。郭襄明知少林寺中武功胜过她的人不计其数,但既见了眼前的不平之事,决不能便此撒手不顾;可是却又担心寺中好手出来截拦,当下一手拉了觉远,一手拉了张君宝,顿足道:“快走快走,有甚么事,下山去慢慢说不好么?”两人只是不动。忽见山坡下寺院边门中冲出七八名僧人,手提齐眉木棍,吆喝道:“哪里来的野姑娘,胆敢来少林寺撒野?”张君宝提起嗓子叫道:“各位师兄不得无礼,这位是……”郭襄忙道:“别说我名字。”她想今日的祸事看来闯得不小,说不定闹下去会不可收拾,可别牵累到爹爹妈妈,又补上一句:“咱们翻山走罢!千万别提我爹爹妈妈和朋友的姓名。”只听得背后山顶上吆喝声响,又涌出七八名僧人来。郭襄见前后都出现了僧人,秀眉深蹙,急道:“你们两个婆婆妈妈,没点男子汉气概!到底走不走?”张君宝道:“师父,郭姑娘一片好意……”", "便在此时,下面边门中又窜出四名黄衣僧人,飕飕飕的奔上坡来,手中都没兵器,但身法迅捷,衣襟带风,武功颇为了得。郭襄见这般情势,便想单独脱身亦已不能,索性凝气卓立,静观其变。当先一名僧人奔到离她四丈之处,朗声说道:“罗汉堂首座尊师传谕:着来人放下兵刃,在山下一苇亭中陈明详情,听由法谕。”\n\n 郭襄冷笑道:“少林寺的大和尚官派十足,官腔打得倒好听。请问各位大和尚做的是大宋皇帝的官儿呢,还是做蒙古皇帝的官?”这时淮水以北,大宋国土均已沦陷,少林寺所在之地自也早该归蒙古管,只是蒙古大军连年进攻襄阳不克,忙于调兵遣将,也无余力来理会丛林寺观的事,因此少林寺一如其旧,与前并无不同。那僧人听郭襄讥刺之言甚是厉害,不由得脸上一红,心中也觉对外人下令传谕有些不妥,合十说道:“不知女施主何事光临敝寺,且请放下兵刃,赴山下一苇亭中奉茶说话。”郭襄听他语转和缓,便想乘此收蓬,说道:“你们不让我进寺,我便希罕了?哼,难道少林寺中有宝,我见一见便沾了光么?”向张君宝使个眼色,低声道:“到底走不走?”张君宝摇摇头,嘴角向觉远一努,意思说是要服侍师父。郭襄朗声道:“好,那我不管啦,我走了。”拔步便下坡去。第一名黄衣僧侧身让开。第二名和第三名黄衣僧却同时伸手一拦,齐声道:“且慢,放下了兵刃。”郭襄眉毛一扬,手按剑柄。第一名僧人道:“我们也不敢留着女施主的兵刃。女施主一到山下,我们立即将宝剑送上,这是少林寺千年来的规矩,还请包涵。”郭襄听他言语有礼,心下踌躇:“倘若不留短剑,势必有场争斗,我孤身一人,如何是阖寺僧众的敌手?但若留下短剑,岂不将外公、爹爹、妈妈、大哥哥、龙姊姊的面子一古脑儿都丢得干净?”她一时沉吟未决,蓦地里眼前黄影晃动,一人喝道:“到少林寺来既带剑,又伤人,世上焉有是理?”跟着劲风飒然,五只手指往剑鞘上抓下来。这僧人若不贸然出手,郭襄一番迟疑之后,多半便会将短剑留下。她和乃姊郭芙的性子大不相同,虽然豪爽,却不鲁莽,眼前处境既极度不利,便会暂忍一时之气,日后再去和外公、爹妈商量,回头找这场子,但对方突然逞强,岂能眼睁睁的让他将剑夺去?那僧人的擒拿手法既狠且巧,一抓住剑鞘,心想郭襄定会向里回夺,一个和尚跟一个年轻女子拉拉扯扯,大是不雅,当下运劲向左斜推,跟着抓而向右。郭襄被他这么一推一抓,果然已拿不牢剑鞘,当即握住剑柄,刷的一声,寒光出匣。那僧人右手将剑鞘夺了过去,左手却有两根手指被短剑顺势割断,剧痛之下,抛下剑鞘,往旁退开。\n\n 众僧人见同门受伤,无不惊怒,挥杖舞棍,一齐攻来。郭襄心想:“一不做二不休,反正今日已不能善罢。”当下使出家传的“落英剑法”,便往山下冲去。众僧人排成三列,仰面挡住。那“落英剑法”乃黄药师从“落英掌法”的路子中演化来,虽不若“玉箫剑法”的精妙,却也是桃花岛的一绝,但见青光激荡,剑花点点,便似落英缤纷,四散而下,霎时间僧人中又有两人受伤。但背后数名僧人跟着抢到,居高临下的夹攻。按理郭襄早已抵挡不住,只是少林僧众慈悲为本,不愿伤她性命,所出招数都非杀手,只求将她打倒,训诫一番,扣下兵刃,将她逐下山去。可是郭襄剑光错落,却也不易攻近身去。众僧初时只道一个妙龄女郎,还不轻易打发?待见她剑法精奇,始知她若非名门之女,便是名师之徒,多半得罪不得,出招时更有分寸,一面急报罗汉堂首座无色禅师。正斗之间,一个身材高瘦老年僧人缓步走近,双手笼在袖中,微笑观斗。两名僧人走到他身前,低声禀告了几句。郭襄已斗得气喘吁吁,剑法凌乱,大声喝道:“说甚么天下武学之源,原来是十多个和尚一拥而上,倚多为胜。”那老僧便是罗汉堂首座无色禅师,听她这么说,便道:“各人住手!”众僧人立时罢手跃开。无色禅师道:“姑娘贵姓,令尊和令师是谁?光临少林寺,不知有何贵干?”郭襄心道:“我爹娘的姓名不能告诉你。我到少林寺来是为了打听大哥哥的讯息,那也不能当众述说。眼下已闹成这等模样,日后爹娘和大哥哥知道了定要怪我,不如悄悄的溜了罢。”说道:“我的姓名不能跟你说,我不过见山上风景优美,这便上来游览玩耍。原来少林寺比皇宫内院还要厉害,动不动便要扣人家兵刃。请问大师,我进了贵寺的山门没有?当日达摩祖师传下武艺,想来也不过教众僧侣强身健体,便于精进修为,想不到少林寺名头越大,武功越高,恃众逞强的名头也越来越响。好,你们要扣我兵刃,这便留下,除非将我杀了,否则今日之事江湖上不会无人知晓。”她本来伶牙俐齿,这件事也并非全是她的过错,一席话只将无色禅师说得哑口无言。郭襄鉴貌辨色,心想:“这番胡闹我固怕人知晓,看来少林寺更加不愿张扬。十多个和尚围斗一个年轻姑娘,说出去有甚么好听?”当下哼的一声,将短剑往地下一掷,举步便行。" ) val book = EBook("倚天屠龙记","张天爱","武侠小说") chapters.foreach(chapter=>book.addChapter(chapter)) book.play() } }
效果展示
“春游浩荡,是年年寒食,梨花时节。白锦无纹香烂漫,玉树琼苞堆 雪。静夜沉沉,浮光霭霭,冷浸溶溶月。人间天上,烂银霞照通彻。 浑似姑射真人,天姿灵秀,意气殊高洁。万蕊参差谁信道,不与群芳 同列。浩气清英,仙才卓荦,下土难分别。瑶台归去,洞天方看清绝 。” 作这一首《无俗念》词的,乃南宋末年一位武学名家,有道之士 。此人姓丘,名处机,道号长春子,名列全真七子之一,是全真教中 出类拔萃的人物。《词品》评论此词道:“长春,世之所谓仙人也, 而词之清拔如此”。这首词诵的似是梨花,其实词中真意却是赞誉一 位身穿白衣的美貌少女,说她“浑似姑射真人,天姿灵秀,意气殊高 洁”,又说她“浩气清英,仙才卓荦”,“不与群芳同列”。词中所 颂这美女,乃古墓派传人小龙女。她一生爱穿白衣,当真如风拂玉树 ,雪裹琼苞,兼之生性清冷,实当得起“冷浸溶溶月”的形容,以“ 无俗念”三字赠之,可说十分贴切。长春子丘处机和她在终南山上比 邻而居,当年一见,便写下这首词来。 这时丘处机逝世已久,小龙女也已嫁与神雕大侠杨过为妻。在河 南少室山山道之上,却另有一个少女,正在低低念诵此词。这少女十 **岁年纪,身穿淡黄衣衫,骑着一头青驴,正沿山道缓缓而上,心 中默想:“也只有龙姊姊这样的人物,才配得上他。”这一个“他” 字,指的自然是神雕大侠杨过了。她也不拉缰绳,任由那青驴信步而 行,一路上山。过了良久,她又低声吟道:“欢乐趣,离别苦,就中 更有痴儿女。君应有语,渺万里层云,千山暮雪,只影向谁去?” 是否继续读取:y 她腰悬短剑,脸上颇有风尘之色,显是远游已久;韶华如花,正当喜 乐无忧之年,可是容色间却隐隐有懊闷意,似是愁思袭人,眉间心上 ,无计回避。 这少女姓郭,单名一个襄字,乃大侠郭靖和女侠黄蓉的次女,有 个外号叫做“小东邪”。她一驴一剑,只身漫游,原想排遣心中愁闷 ,岂知酒入愁肠固然愁上加愁,而名山独游,一般的也是愁闷徒增。 河南少室山山势颇陡,山道却是一长列宽大的石级,规模宏伟,工程 着实不小,那是唐朝高宗为临幸少林寺而开凿,共长八里。郭襄骑着 青驴委折而上,只见对面山上五道瀑布飞珠溅玉,奔泻而下,再俯视 群山,已如蚁蛭。顺着山道转过一个弯,遥见黄墙碧瓦,好大一座寺 院。 她望着连绵屋宇出了一会神,心想:“少林寺向为天下武学之源 ,但华山两次论剑,怎地五绝之中并无少林寺高僧?难道寺中和尚自 忖没有把握,生怕堕了威名,索性便不去与会?又难道众僧侣修为精 湛,名心尽去,武功虽高,却不去和旁人争强赌胜?”她下了青驴, 缓步走向寺前,只见树木森森,荫着一片碑林。石碑大半已经毁破, 字迹模糊,不知写着些甚么。心想:“便是刻凿在石碑上的字,年深 月久之后也须磨灭,如何刻在我心上的,却是时日越久反而越加清晰 ?”瞥眼只见一块大碑上刻着唐太宗赐少林寺寺僧的御札,嘉许少林 寺僧立功平乱。碑文中说唐太宗为秦王时,带兵讨伐王世充,少林寺 和尚投军立功,最著者共一十三人。其中只昙宗一僧受封为大将军, 其余十二僧不愿为官,唐太宗各赐紫罗袈裟一袭。她神驰想象:“当 隋唐之际,少林寺武功便已名驰天下,数百年来精益求精,这寺中卧 虎藏龙,不知有多少好手。”郭襄自和杨过、小龙女夫妇在华山绝顶 分手后,三年来没得到他二人半点音讯。她心中长自记挂,于是禀明 父母,说要出来游山玩水,实则是打听杨过的消息,她倒也不一定要 和他夫妇会面,只须听到一些杨过如何在江湖上行侠的讯息,也便心 满意足了。偏生一别之后,他夫妇从此便不在江湖上露面,不知到了 何处隐居,郭襄自北而南,又从东至西,几乎踏遍了大半个中原,始 终没听到有人说起神雕大侠杨过的近讯。这一日她到了河南,想起少 林寺中有一位僧人无色禅师是杨过的好友,自己十六岁生日之时,无 色瞧在杨过的面上,曾托人送来一件礼物,虽然从未和他见过面,但 不妨去问他一问,说不定他会知道杨过的踪迹,这才上少林寺来。正 出神间,忽听得碑林旁树丛后传出一阵铁链当啷之声,一人诵念佛经 :“是时药叉共王立要,即于无量百千万亿大众之中,说胜妙伽他曰 :由爱故生忧,由爱故生怖;若离于爱者,无忧亦无怖……”郭襄听 了这四句偈言,不由得痴了,心中默默念道:“由爱故生忧,由爱故 生怖;若离于爱者,无忧亦无怖。”只听得铁链拖地和念佛之声渐渐 远去。郭襄低声道:“我要问他,如何才能离于爱,如何能无忧无怖 ?”随手将驴缰在树上一绕,拨开树丛,追了过去。只见树后是一条 上山的小径,一个僧人挑了一对大桶,正缓缓往山上走去。郭襄快步 跟上,奔到距那僧人七八丈处,不由得吃了一惊,只见那僧人挑的是 一对大铁桶,比之寻常水桶大了两倍有余,那僧人颈中、手上、脚上 ,更绕满了粗大的铁链,行走时铁链拖地,不停发出声响。这对大铁 桶本身只怕便有二百来斤,桶中装满了水,重量更是惊人。郭襄叫道 :“大和尚,请留步,小女子有句话请教。” 是否继续读取:n Process finished with exit code 0
8、内部类
8.1:使用内部类的目的
1.封装代码:将代码进行封装,达到重用的效果。
2.隐藏实现:在内部类中通过【访问控制修饰符】来决定是否对外开放。
若定义了一个【私有的内部类(private)】,那么【这个内部类就只能在外部类的内部使用,外部类的客户端无法直接访问或实例化这个内部类,从而实现了隐藏实现】。这种方式可以有效地封装类的实现细节,提高代码的安全性和可维护性。
3.易维护易扩展
8.2:具体讲解
知识点一:Scala中内部类是外部类对象的成员
/* Java中内部类是【外部类的成员】: InClass ic = new OutClass.InClass() Scala中内部类是【外部类对象的成员】: val out = new OutClass(); val in = new out.InClass(); */ //外部类 class OutClass { //内部类:隐藏实现 class InClass{ override def toString: String = "InClass" } private val in:InClass = new InClass() override def toString: String = s"OutClass{${in}}" } object ScalaOOP { def main(args: Array[String]): Unit = { //创建外部类对象 val out = new OutClass println(out) //外部访问内部类 => 内部类是外部类对象的资源 val in = new out.InClass println(in) } } -------------------------- OutClass{InClass} InClass --------------------------
知识点二:内部类推荐写入伴生对象中
import scala.cha06.OutClass.InClass //外部类 class OutClass { private val in:InClass = new InClass() override def toString: String = s"OutClass{${in}}" } //内部类:【推荐】写到【伴生对象】中 object OutClass{ class InClass{ override def toString: String = "InClass" } } object ScalaOOP { def main(args: Array[String]): Unit = { //创建外部类对象 val out = new OutClass println(out) //外部访问内部类 => 内部类是外部类对象的资源 val in = new OutClass.InClass println(in) } } -------------------------- OutClass{InClass} InClass --------------------------
9、样例类
9.1:样例类基本知识
样例类: 1.默认状态下:【不可变值】的对象 样例类构造参数【默认声明】为 val,自动生成 getter【不可变值】 样例类的构造参数若声明为 var,自动生成 getter & setter【可变值】 2.自动生成: 样例类自动生成伴生对象 样例类自动实现的其他方法:toString,copy,equals,hashCode 3.【样例类伴生对象实现】的方法:apply, unapply(用于模式匹配) 4.【注意点】: 父类可以是样例类或普通类,但其叶子节点[最底层节点]不能是样例类。
9.2:样例类详细案例讲解
一:模式匹配案例
// 普通类的模式匹配案例 case class Student(name:String, age:Int) // 构造参数默认 val case class Point(var x:Int,var y:Int) // var 需要显式声明 // 追加伴生对象并实现 apply & unapply 之后,不再报错 object Point{ //形成对象 def apply(x: Int, y: Int): Point = new Point(x, y) //拆解,提取对象中内容 def unapply(arg: Point): Option[(Int, Int)] = Some((arg.x,arg.y)) } val obj:Any = Student("张三",18) val info = obj match { case Student(_,22) => "22" case Student(name,_) if name.startsWith("张") => "姓张" case Point(a,_) => s"$a" // 报错 cannot resolve symbol } ------------------- 姓张 -------------------
二:验证可变值与不可变值案例
// 默认情况下val:【不可变值】的对象 object ScalaOOP { def main(args: Array[String]): Unit = { case class Point(x:Int,y:Int) val point: Point = Point(10, 20) println(point.x)//获取信息 } } ------------ 10 ------------ // var:可变值 object ScalaOOP { def main(args: Array[String]): Unit = { case class Point(var x:Int,var y:Int) val point: Point = Point(10, 20) point.x = 21 println(point.x) } } ------------ 21 ------------
10、枚举【了解】
/* 单例对象通过继承 Enumeration 实现枚举创建,简单易用,但不可扩展 通常用于定义一个有限取值范围的常量 */ class Choice extends Enumeration { val FIRST_CHOICE = Value(0) val FIRST_SECOND = Value(1) val FIRST_THIRD = Value(2) } object ScalaOOP { def main(args: Array[String]): Unit = { val choice: Choice.Value = Choice.FIRST_CHOICE val num: Int = choice match { case Choice.FIRST_CHOICE => 11 case Choice.SECOND_CHOICE => 12 case Choice.THIRD_CHOICE => 13 } println(num) } } ------------ 11 ------------
11、泛型
11.1:泛型定义
泛型的定义:类型参数化,主要用于【集合】。不同于 Java ,scala中泛型被定义在 [] 中。
11.2:泛型简单体验
//泛型体验 class Many[T](t:T){ val _t:T = t override def toString: String = _t.toString } object ScalaOOP { def main(args: Array[String]): Unit = { val many:Many[String] = new Many[String]("123") println(many) } } ------------- 123 -------------
11.3:泛型的边界定义
class GrandFather(name:String) { val _name:String = name override def toString: String = _name } object GrandFather{ def apply(name: String): GrandFather = new GrandFather(name) } class Father(name:String) extends GrandFather(name:String) {} object Father{ def apply(name: String): Father = new Father(name) } class Son(name:String) extends Father(name:String) {} object Son{ def apply(name: String): Son = new Son(name) } class GrandSon(name:String) extends Son(name:String){} object GrandSon{ def apply(name: String): GrandSon = new GrandSon(name) } /* 泛型边界定义 上边界:T<:A 泛型为某个类型的子类 下边界:T>:A 泛型为某个类型的父类 */ // 1.只能是比Father小的类型 class MyArray[T <: Father](items:T*) { def join(sep:String) = items.mkString(sep) } // Type GrandFather does not conform to 【 upper bound 】 Father of type parameter T val arr:MyArray[GrandFather] = ... ================================================================================= // 2.只能是比Son大的类型 class MyArray[T >: Son](items:T*) { def join(sep:String) = items.mkString(sep) } // Type GrandSon does not conform to 【 lower bound 】 Son of type parameter T val arr:MyArray[GrandSon] = ...
11.4:泛型的多态
class GrandFather(name:String) { val _name:String = name override def toString: String = _name } object GrandFather{ def apply(name: String): GrandFather = new GrandFather(name) } class Father(name:String) extends GrandFather(name:String) {} object Father{ def apply(name: String): Father = new Father(name) } class Son(name:String) extends Father(name:String) {} object Son{ def apply(name: String): Son = new Son(name) } class GrandSon(name:String) extends Son(name:String){} object GrandSon{ def apply(name: String): GrandSon = new GrandSon(name) } /* 泛型的变化 => 影响泛型类的变化 型变:多态 协变:[+T] 若A是B的子类,则 C[A]为C[B]的子类 ✔【推荐】 逆变:[-T] 若A是B的子类,则 C[B]为C[A]的子类 不变:[T] 默认 */ class MyArray[+T](items:T*) { def join(sep:String) = items.mkString(sep) } // Father 是 Son 的父类,则 MyArray[Father] 就是 MyArray[Son] 的父类 val arr:MyArray[Father] = new MyArray[Son](Son("henry"),Son("ariel")) ================================================================================= class MyArray[-T](items:T*) { def join(sep:String) = items.mkString(sep) } // Father 是 Son 的子类,则 MyArray[Son] 就是 MyArray[Father] 的子类 val arr:MyArray[Son] = new MyArray[Father](Son("henry"),Son("ariel")) ================================================================================= class MyArray[T](items:T*) { def join(sep:String) = items.mkString(sep) } // 所有泛型都必须为 Son val arr:MyArray[Son] = new MyArray[Son](Son("henry"),Son("ariel"))
12、包与包对象
/* 【包】 包命名规则:字母、数字、下划线、点,不能以数字开头,在【一个类文件中可以定义多个并列的包】 导包的不同方式 import com.kgc.Person 方便使用类 Person import com.kgc._ 方便使用 com.kgc 包中的所有类 import com.kgc.Person._ 方便使用类 Person 中的所有属性和方法 import com.kgc.{Person=>PS,Book} 只导入包中 Person和Book,并将Person重命名为PS 不同于Java import 导包语句可以出现在任意地方 可以导入包、类、类成员 */ // 单个文件多包结构:【资源】按【包名】语义【分类存放】,方便管理和使用 ----------------------- Test.scala START ---------------------------- package cha03{ import cha03.util.Sorts object PackageTest { def main(args: Array[String]): Unit = { val array: Array[Int] = Array(3, 1, 5, 4, 2) Sorts.insertSort(array) array.foreach(println) } } } package cha03.util{ object Sorts{ def insertSort(array: Array[Int]): Unit ={ import scala.util.control.Breaks._ for(i<- 1 until array.length){ val t = array(i) var j = i-1 breakable({ while (j>=0){ if(array(j)>t){ array(j+1) = array(j) }else{ break() } j-=1 } }) array(j+1) = t } } } } ----------------------- Test.scala END ---------------------------- /* 【包对象】 包中可以包含:类、对象、特质... 包对象可以包含:除了类、对象、特质外,还可以包含变量和方法 */ package cha03{ import cha03.util.Constants._ import cha03.util.Constants.{DataFormat=>DF} object PackageTest { def main(args: Array[String]): Unit = { println(PI*2*2) println(getQuarter(5)) val format: DF = DF(2024, 3, 29) println(format.stdYMD()) println(format.stdFull()) println(format.timestamp()) } } } package cha03.util{ import java.util.Calendar // 包对象 package object Constants{ // 变量 val PI:Float = 3.14f // 方法 def getQuarter(month:Int)=(month-1)/3+1 // 类 class DataFormat( year:Int,month:Int,day:Int, hour:Int,minute:Int,second:Int, millis:Int){ private var _year:Int = year private var _month:Int = month private var _day:Int = day private var _hour:Int = hour private var _minute:Int = minute private var _second:Int = second private var _millis:Int = millis def this(year:Int,month:Int,day:Int){ this(year,month,day,0,0,0,0) } def stdYMD():String = s"${_year}-${_month}-${_day}" def stdFull():String = s"${_year}-${_month}-${_day} ${_hour}:${_minute}:${_second}.${_millis}" def timestamp():Long = { val cld = Calendar.getInstance() cld.set(_year,_month,_day,_hour,_minute,_second) cld.set(Calendar.MILLISECOND,555) cld.getTimeInMillis } } } object DataFormat{ def apply(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int, millis: Int): DataFormat = new DataFormat(year, month, day, hour, minute, second, millis) def apply(year: Int, month: Int, day: Int): DataFormat = new DataFormat(year, month, day) } } // 导包的形式 import pack_name 包本身 import pack_name._ 包下面的所有资源 import pack_name.{A=>AS,B} 包下面部分资源 import pack_name.Class 类本身 import pack_name.Class.{PI,show} 类中的方法属性等 import pack_name.Class._ 类下面的所有资源