Scala学习(八)练习
Scala中继承&练习 |
1. 扩展如下的BankAccount类,新类CheckingAccount对每次存款和取款都收取1美元的手续费
class BankAccount ( initialBalance: Double) {
private var balance = initialBalance
def deposit (amount: Double) = { balance += amount; balance }
def withdraw(amount: Double)={ balance -= amount; balance }
}
程序代码:
- class BankAccount(initialBalance:Double){
- private var balance=initialBalance
- def deposit(amount:Double)={
- balance+=amount
- balance
- }
- def withdraw(amount:Double)={
- balance-=amount
- balance
- }
- def currentBalance=balance
- }
- //一种实现
- class checkingAccount (initialBalance:Double) extends BankAccount(initialBalance){
- override def deposit(amount:Double)={
- super.deposit(amount-1)
- }
- override def withdraw(amount:Double)={
- super.withdraw(amount+1)
- }
- }
- object checkingAccount{
- val cha=new checkingAccount(1000)
- val dbal=1000
- val wbal=800
- def main(args: Array[String]): Unit = {
- cha.deposit(dbal)
- println("存入 :"+dbal+"余额: "+cha.currentBalance)
- cha.withdraw(wbal)
- println("取出 :"+wbal+"余额: "+cha.currentBalance)
- }
- }
运行结果:
存入 :1000 余额: 1999.0
取出 :800 余额: 1198.0
2. 扩展前一个练习的BankAccount类,新类SavingsAccount每个月都有利息产生( earnMonthlylnterest方法被调用 ),并且有每月三次免手续费的存款或取款。在eamMonthlylnterest方法中重置交易计数
程序代码:
- class SavingsAccount(initialBalance:Double) extends BankAccount(initialBalance){
- private var freeCount=3
- private val interestRate=0.03
- def CurrentCount = freeCount
- def earnMonthlyInterrest:Double={
- freeCount=3
- super.deposit(super.deposit(0)*interestRate)
- super.deposit(0)*interestRate
- }
- override def deposit(amount:Double):Double={
- if(freeCount>0){
- freeCount-=1
- super.deposit(amount)
- }else{
- super.deposit(amount-1)
- }
- }
- override def withdraw(amount:Double):Double={
- if(freeCount>0){
- freeCount-=1
- super.withdraw(amount)
- }else{
- super.withdraw(amount+1)
- }
- }
- }
- object SaveTest{
- val dbal=1000
- val wbal=100
- var interest=0.0
- val sa=new SavingsAccount(1000)
- def main(args: Array[String]): Unit = {
- for(i<- 1 to 32){
- if(i>=1&& i<=4){
- sa.deposit(1000)
- println(i+"号存入: "+dbal+"余额: "+sa.currentBalance+"剩余免费次数: "+sa.CurrentCount)
- }else if(i>=29&&i<=31){
- if(i==30)
- interest=sa.earnMonthlyInterrest
- sa.withdraw(100)
- println(i+"号取出: "+wbal+"余额: "+sa.currentBalance+"剩余免费次数: "+sa.CurrentCount)
- }
- }
- println("一个月的利息为: "+interest+"剩余免费次数: "+sa.CurrentCount)
- }
- }
运行结果:
号存入: 1000余额: 2000.0 剩余免费次数: 2
号存入: 1000余额: 3000.0 剩余免费次数: 1
号存入: 1000余额: 4000.0 剩余免费次数: 0
号存入: 1000余额: 4999.0 剩余免费次数: 0
号取出: 100余额: 4898.0 剩余免费次数: 0
号取出: 100余额: 4944.94 剩余免费次数: 2
号取出: 100余额: 4844.94 剩余免费次数: 1
一个月的利息为: 151.3482 剩余免费次数: 1
3. 翻开你喜欢的Java或C++教科书,一定会找到用来讲解继承层级的示例,可能是员工、宠物、图形或类似的东西,用Scala来实现这个示例
- abstract class Animal{
- def run
- }
- class Cat extends Animal{
- override def run=println("I can run,miao!")
- }
- class Dog extends Animal{
- override def run=println("I can run,wang!")
- }
- object AnimalTest {
- def main(args: Array[String]): Unit = {
- val cat=new Cat
- val dog=new Dog
- cat.run
- dog.run
- }
- }
运行结果:
I can run,miao!
I can run,wang!
4. 定义一个抽象类ltem,加入方法price和description。Simpleltem是一个在构造器中给出价格和描述的物件。利用val可以重写def这个事实。Bundle是一个可以包含其他物件的物件。其价格是打包中所有物件的价格之和。同时提供一个将物件添加到打包当中的机制,以及一个合适的description方法
程序代码:
- abstract class Item{
- def price:Double
- def description:String
- }
- class SimpleItem(override val price:Double,override val description:String) extends Item{
- }
- class Bundle() extends Item{
- val itemList=scala.collection.mutable.ArrayBuffer[Item]()
- def addItem(item:Item){
- itemList+=item
- }
- override def price={
- var p:Double=0
- itemList.foreach(i=>p=p+i.price)
- p
- }
- override def description={
- var des=""
- itemList.foreach(i=>des=des+i.description+"")
- des
- }
- }
- object ItemTest {
- val bundle=new Bundle
- def main(args: Array[String]): Unit = {
- val priceArr=Array(2.5,100,3.5,40,32.5)
- val desArr=Array("铅笔","水杯","笔记本","火腿肠","鼠标")
- for(i <- 0 until 5){
- bundle.addItem(new SimpleItem(priceArr(i),desArr(i)))
- }
- println("购物篮信息如下:")
- bundle.itemList.foreach(item=>println("描述: "+item.description+"价格: "+item.price))
- println("所购物品如下: "+bundle.description)
- println("本次购物合计: "+bundle.price+"¥")
- }
- }
运行结果:
购物篮信息如下:
描述: 铅笔价格: 2.5
描述: 水杯价格: 100.0
描述: 笔记本价格: 3.5
描述: 火腿肠价格: 40.0
描述: 鼠标价格: 32.5
所购物品如下: 铅笔水杯笔记本火腿肠鼠标
本次购物合计: 178.5¥
5. 设计一个Point类,其x和y坐标可以通过构造器提供。提供一个子类LabeledPoint,其构造器接受一个标签值和x、y坐标,比如:
new LabeledPoint("Black Thursday", 1929, 230.07)
程序代码:
- class Point(val x:Double,val y:Double) {
- override def toString="x= "+x+" y= "+y
- }
- class LabelPoint(val label:String,override val x:Double,override val y:Double)extends Point(x,y){
- override def toString ="label= "+label+"x= "+x+"y= "+y
- }
- object PointTest{
- def main(args: Array[String]): Unit = {
- val point=new Point(2,3)
- val lpoint=new LabelPoint("圆形",2,3)
- println(point)
- println(lpoint)
- }
- }
运行结果:
x= 2.0 y= 3.0
label= 圆形 x= 2.0y= 3.0
6. 定义一个抽象类Shape、一个抽象方法centerPoint,以及该抽象类的子类Rectangle和Circle。为子类提供合适的构造器,并重写centerPoint方法
程序代码:
- abstract class Shape {
- abstract def centerPoint: Point
- }
- class Rectangle(p1: Point, p2: Point, p3: Point) extends Shape {
- override def centerPoint = {
- //略
- }
- }
- class Circle(p1: Point, p2: Point, p3: Point) extends Shape {
- override def centerPoint = {
- //略
- }
- }
运行结果:
7. 提供一个Square类,扩展自java.awt.Rectangle并且有三个构造器:一个以给定的端点和宽度构造正方形,一个以(0,0)为端点和给定的宽度构造正方形,一个以(0,0)为端点、0为宽度构造正方形。
程序代码:
- import java.awt.Point
- import java.awt.Rectangle
- class Squre extends Rectangle{
- height=0
- width=0
- x=0
- y=0
- def this(p:Point,w:Int){
- this()
- this.height=w
- this.width=w
- this.x=p.x
- this.y=p.y
- }
- def this(width:Int){
- this(new Point(0,0),width)
- }
- }
- object SqureTest {
- def main(args: Array[String]): Unit = {
- val rect1=new Squre()
- val rect2=new Squre(2)
- val rect3=new Squre(new Point(2,3),5)
- println(rect1)
- println(rect2)
- println(rect3)
- }
- }
运行结果:
org.hebut.yu.two.Squre[x=0,y=0,width=0,height=0]
org.hebut.yu.two.Squre[x=0,y=0,width=2,height=2]
org.hebut.yu.two.Squre[x=2,y=3,width=5,height=5]
8. 编译的Person和SecretAgent类并使用javap分析类文件。总共有多少name的getter方法,它们分别取什么值
程序代码:
class Person ( val name: String ) {
override def toString=getClass.getName+"name="+ name+ "]"
}
class SecretAgent (codename: String) extends Person (codename) {
override val name = "secret" // 不想暴露真名…
override val toString = "secret" // …或类名
}
执行命令:
javap -p : 查看编译的内容
javap -c : 查看想详细操作指令
javap -v : 查看常量池
运行结果:Person.scala
运行结果:Person.scala
分析:可以看到两个类中都有name()方法,但是子类覆写了父类的。SecretAgent和Person不一样的是name设置了默认值,用-v查看,name的secrect实际上是在构造函数中设置的
执行命令:javap -v org.hebut.yu.Person
执行命令:javap -v org.hebut.yu.SecretAgent
9. 在Creature类中,将val range替换成val def。如果你在Ant子类中也用def的话会有什么效果,如果在子类中使用val又会有什么效果,为什么
程序代码:
class Creature {
val range : Int=10
val env: Array[Int] = new Array[Int] ( range)
}
class Ant extends Creature {
override val range=2
}
class Ant extends {
override val range=2
} with Creature
描述:★★★★★★
def覆写def,子类的env可以正确初始化。而用val覆写def,env会被初始化成0长度。这个跟val覆写val的道理是一样的。父类和子类同时存在私有的同名变量range和相同的range的getter,但是父类构造函数先被调用,却在其中调用子类的getter。因为父类 的getter以被子类覆写。子类的range因为此时还没初始化,所以返回了0。父类构造函数,错误地使用0来初始化了env。这种行为本身就是个坑,但是也提供了非常大的灵活性。面向对象的Template设计模式就依赖这种行为实现的,所以还是多多善用为妙。
10. 文件scala/collection/immutable/Stack.scala包含l如下定义:
class Stack[A] protected ( protected val elems: List[Al )
请解释protected关键字的含义
前一个protected是指主构造器的权限, 即默认情况下,是不能已传入elems的方式创建Stack对象的,elems的protected指的是这个参数只有子类才能访问
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【Sunddenly】。本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Scala学习(八)练习的更多相关文章
- Scala学习八——继承
一.本章要点 extends,final关键字和Java一样 重写方法时必须使用override 只有主构造器可以调用超类的构造器 可以重写字段 二.扩展类 Scala扩展类和Java一样(使用ext ...
- Scala学习(八)---Scala继承
Scala继承 摘要: 在本篇中,你将了解到Scala的继承与Java和C++最显著的不同.要点包括: 1. extends.final关键字和Java中相同 2. 重写方法时必须用override ...
- Scala学习资源
Scala学习资源: Scala官方网站:http://www.scala-lang.org/ Scala github:https://github.com/scala/scala Twitter ...
- 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习
下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...
- Python Tutorial 学习(八)--Errors and Exceptions
Python Tutorial 学习(八)--Errors and Exceptions恢复 Errors and Exceptions 错误与异常 此前,我们还没有开始着眼于错误信息.不过如果你是一 ...
- 机器学习(三)--- scala学习笔记
Scala是一门多范式的编程语言,一种类似Java的编程语言,设计初衷是实现可伸缩的语言.并集成面向对象编程和函数式编程的各种特性. Spark是UC Berkeley AMP lab所开源的类Had ...
- SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- 【Scala】Scala学习资料
Scala学习资料 java 树形 分类器_百度搜索 决策树分类器-Java实现 - CSDN博客 KNN分类器-Java实现 - CSDN博客 学习:java设计模式—分类 - 飞翔荷兰人 - 博客 ...
- Scala学习网址
scala学习网址为:https://twitter.github.io/scala_school/zh_cn https://www.zhihu.com/question/26707124
随机推荐
- 我喜欢 Google Flutter
在 Google I/O ’17 上,Google 向我们介绍了 Flutter —— 一款新的用于创建移动应用的开源库. 正如你所想的那样,Flutter 是能够帮助创建拥有漂亮 UI 界面的跨平台 ...
- Android 官方DEMO BasicNetworking
本示例演示如何使用Android API检查网络连接. Demo下载地址:https://github.com/googlesamples/android-BasicNetworking/#readm ...
- 口碑订单,ERP本地加/退菜无法回流至手机端的解决办法-订单金额不统一erp本地加菜H5没有
关于 口碑订单,ERP本地加/退菜无法回流至手机端的解决办法-订单金额不统一erp本地加菜H5没有 1. 2. 3. PS:是正餐后付的务必要选择口碑后付 完成以上设置即可
- SQL Server 锁实验(INSERT加锁探究)
insert语句: 其上锁情况为: insert语句会对表上的所有索引作出更新,因此这里看到的索引列较多,我们先把所有的索引搞出来看看: 可以看到所有索引都涉及到了,然后我们来仔细分析下加锁情况: 1 ...
- Django + Uwsgi + Nginx 实现生产环境部署
本节内容 uwsgi 介绍 uwsgi安装使用 nginx安装配置 django with nginx 如何在生产上部署Django? Django的部署可以有很多方式,采用nginx+uwsgi的方 ...
- C#从http上拿返回JSON数据
C#如何拿到从http上返回JSON数据? 第一章:C#如何拿到从http上返回JSON数据? 第二章:C#如何解析JSON数据?(反序列化对象) 第三章:C#如何生成JSON字符串?(序列化对象) ...
- 一、Selenium 工作原理
1.Selenium介绍 Selenium是用于测试Web应用程序用户界面UI的常用框架.端对端的功能测试.并且在一个多个浏览器中操作. 目前Seienium 组件主要包括Selenium IDE ...
- 通过jquery隐藏和显示元素
通过jquery隐藏和显示元素 调用jquery本身提供的函数 $("xxx").hide();//隐藏xxx $("xxx").show();//显示xxx ...
- [Hive_add_6] Hive 实现 Word Count
0. 说明 Hive 通过 explode()函数 和 split()函数 实现 WordConut 1. Hive 实现 Word Count 方式一 1.1 思路 将每一行文本变为 Array 数 ...
- C语言 统计一串字符中空格键、Tab键、回车键、字母、数字及其他字符的个数(Ctrl+Z终止输入)
//凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ #include<stdio.h> void main(){ , num=, blank=, ...