作业评讲|学习笔记

简介: 快速学习作业评讲。

开发者学堂课程【Scala 核心编程-基础作业评讲】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/609/detail/8992


作业评讲

 

内容介绍

一、对象

二、继承

 

一、对象

1、编写一个 Conversions 对象,加入 inchesToCentimetersgallonsToLiters  milesToKilometers 方法

解析:本题比较简单,查找单位之间的换算,写一个 objet  Conversions 对象,再定义三个方法就可解答。

答案:

object Conversions{

//英寸->厘米,英寸和厘米的单位转换是2.54。

def inchesToSantimeters(value:Double)=value * 2.54

//加仑->升,加仑和升单位转换是3.78541178。

def gallonsToLiters(value:Double)=value* 3.78541178

//英里->公里,英里和公里的单位转换是1.609344。

def milesToKilometers(value:Double)=value * 1.609344

}

2、定义一个 Point 类和一个伴生对象,使得可以不用 new 而直接用 Point(3,4)来构造 Point 实例 apply 方法的使用

解析:构建对象有三种形式,第一种是 new,第二种是 apply,第三种是匿名子类。这里在 point 中加一个 apply 方法,apply 方法中可以接受两个指数,把 new隐藏在 apply 方法中。

答案:

//Point 类

class Point(x:Int = 0,y:Int=o) {

//在类中定义了两个属性,使用主构造器的方式初始化属性。

var x1=x

var y1=y

}

object Point {

//因为apply 方法中调用了 new point ,所以就会在 apply 方法中返回一个 Point

def apply(x:Int=0,y:Int =0)= new Point(x,y)

测试:

object Exercise02 {

def main(args: Array[string]): unit = {

//两个值分别代表横坐标和纵坐标。

//触发 apply 方法。

Val point=point(3,4).

Println(point)

}

}

运行结果:返回了一个 point 实例。

image.png

3、编写一个 Scala 应用程序,使用 App 特质,以反序打印命令行参数,用空格隔开。举例来说,scala Reverse Hello World 应该打印 World Hello

解析:App 特质中包含了 main 方法。所以继承了 App 特质后就可以直接执行语句,当作程序的入口。

答案:

object Exercise03 { extends App{

//app 中隐藏了一个主函数 def main(args:Array[String]):unit= 。因为 app 中已经定义好了一个主函数,并且参数就是 args,所以这里可以直接使用参数 args。

Val args2=args.reverse

Println(args2)

}

//首先可以随便打印一个内容使 idea 能够被识别。

object Exercise03 { extends App{

Println(“hello~~”)

}

找到菜单栏的 Edit Configurations ,点击 program arguments 程序参数,在其中添加内容:hello world abc。运行程序,打印出一个地址:

[L java.lang.String;@3498ed。重新修改代码为 Println(args2.mkstring(“”)),打印结果:abc world hello。

4、编写一个扑克牌4种花色的枚举让其 toString 方法分别返回,,,,并实现一个函数检查某张牌的花色是否为红色

解析:Type 的用法讲解

//type 用于给类型起别名。Type myint =int 表示 myint 可以当作 int 使用,相当于给 int 取了一个别名,或者自定义了一个类型。

Type myint =int

//把888赋给了 num1,类型是 myint,myint 就是 int 。

Val num1:myint=888

Println(“num1=”+num1)

}

}

运行代码输出:num1=888

答案:

// Enumeration 是枚举。

object Suits extends Enumeration{

//给 Value 类型取别名

type Suits = Value

///使用 value 中的apply方法创建了一个实例,此 value 是从Enumeration 中继承来的。

val Spade = Value("")

val Club = Value("")

val Heart = Value("���")

val Diamond = value(“”)

//这是 Suits 中的四个实例

//重写 toString 方法

override def toStringo:String={

Suits.values.mkString(",")

}

}

//打印结果。

Println(suits)

}

Suits 是一个 object ,这样相当于输出了 suits 对应的隐藏在底层的module$。由于重写了 to string 方法,所以就会调用 Suits.values 方法,而 Suits.values 则会将所有的实例都取出来。

运行结果:输出了四个花色,如果没有 Suits.values.mkString(",") 则表示不输出任何内容。

image.png

//验证花色是否为红色。def isRed(card: Suits)= card == Heart || card == Diamond,在 isRed 中接受一个 Suits然后判断是否为���或者。

def isRed(suits:suits):Boolean={

if suit== Heart || suit==Diamond)

true

}else{

False

}

}

}

这样的写法不够简便,所以直接写 def isRed(card: Suits)= card == Heart || card == Diamond 即可。

测试:object 中的方法可以直接调用。Suits.isRed() 要求传入花色的一种,而花色已经在 suits 中了,所以调用时直接点击 suits 就会显示出现四个实例 club,Diamond,Heart,Spade。

//传入一个红心,应该返回 true。

Suits.isRed(suits.Heart)

//传入一个黑桃,应该返回 false。

Suits.isRed(suits.spade)

//注意用 println 函数打印,否则不能输出结果。

Println(Suits.isRed(suits.Heart))

Println(Suits.isRed(suits.spade))

运行结果:

true

false

 

二、继承

1、扩展如下的 BankAccount 类,新类 CheckingAccount 对每次存款和取款都收取1美元的手续费

解析:题目已经给出了 BankAccount 类,要求根据这个类写一个新类 CheckingAccount。 相当于 BankAccount 是普通银行账号类,而 checkingAccount 是基于 BankAccount 进行扩展的账号类。

这是题目给出的普通账号类:

//初始化余额

class BankAccount (initialBalance:Double){

private var balance = initialBalance

//存款,直接在余额上加上存款

def deposit (amount :Double)= { balane += amount; balance}

//取款直接从余额减去取款并且返回余额。

//此代码还可以加入对余额的判断。

def withdraw(amount : Double)= {balance -= amount; balance}

}

答案:

新类 CheckingAccount 对每次存款和取款都收取1美元的手续费BankAccount 类的代码都可以继承过来,但是存款和取款的方法需要重写。

//继承 BankAccount,将 depositwithdraw进行 overwrite。比如存款存了9元,那么在余额中体现为8元,取款取了10元,但实际上余额会减掉11元。

class BankAccount (initialBalance: Double){

private var balance = initialBalance

def deposit(amount:Double)={balance+=amount;balance}

def withdraw(amount:Double)={balance-=amount;balance}

}

//利用主构造器调用了 BankAccount 的主构造器。

class CheckingAccount(initialBalance:Double) extends BankAccount (initialBalance){

//重写方法时不需要完全重写,用 super 继承即可。

override def deposit(amount:Double)=super.deposit (amount-1)

override def withdraw(amount:Double)=super.withdraw (amount+1)

}

//为了测试结果是否正确,在主类下加入一个查询余额的方法。

Def query():unit={

Ptintln(当前余额为”+this.balance)

测试:

object BankAccountDemo {

def main(args:Array[String]):unit={

//存入100元。运行结果:当前余额为100.0

val checkingAccount = new checkingAccount(100)

checkingAccount.query()

//取出10元并查询余额。由于手续费是1美元,所以取出10元后余额应该是89元。运结果:当前余额89.0

checkingAccount.withdraw(10)

checkingAccount.query()

//存入10元并查询余额。由于手续费是1美元,所以存入10元后余额应该是98元。运行结果:当前余额98.0

checkingAccount.deposit(10)

checkingAccount.query()

}

}

2、扩展前一个练习的 BankAccount 类,新类 SavingsAccount 每个月都有利息产生(earnMonthlyInterest方法被调用),并且有每月三次免手续费的存款或取款。在 earnMonthlyInterest 方法中重置交易计数。

答案:

//普通账号

class BankAccount(initialBalance: Double){

private var balance = initialBalance

def deposit(amount:Double)={balance+=amount;balance}

def withdraw(amount:Double)={balance=amount;balance}

}

Class savingsAccount (initialBalance:Double) extends

BankAccount(initialBalance){

//定义了一个免手续费的次数

private var num:Int=_

//每月初,系统调用该方法计算利息,同时将 num=3

def earmonthlyinterest()={

num=3

//一般利息计算应该是余额*利率,这里假定利息是一美元。

super.deposit(1)

}

//取款时如果 num<0就收手续费,否则不收手续费。

override def deposit(amount:Double):Double ={

num-=1

if(num<0)

super.deposit(amount-1)

else

super.deposit(amount)

}

//取款逻辑和存款一样,如果 num<0存款就会收手续费,否则不收

override def withdraw(amount:Double):Double ={

num-=1

if(num<0) super. withdraw(amount-1) else super. Withdraw (amount)

}

}

解决该问题需要有思维的转换,充分利用父类对子类进行扩展。

测试:

//查看当前账户余额应该是100元。

val savingAccount = new savingAccount(100)

savingAccount.query()

//月初计算利息,账户余额应为101元。

savingAccount.earnMonthlyinterest()

//取款三次,每次取出10元

savingAccount.withdraw(10)

savingAccount.withdraw(10)

savingAccount.withdraw(10)

//查询账户余额,此时账户余额应是71元。

savingAccount.query()

运行结果:

当前余额为100.0

当前余额为71.0

//再次取出10元,此时还应该扣除手续费,所以账户余额应该是71-10-1=60。

savingAccount.withdraw(10)

savingAccount.query()

}

}

运行结果:当前余额为60.0

3、设计一个 point 类,X 和 Y 坐标可以通过构造器提供。提供一个子类 LabeledPoint,其构造器接受一个标签值和 x,y 坐标,比如:newLabeledPoint(“Black Thursday” ,1929,230.07)

解析:本题主要考察构造器的使用。

答案:

class Point(x:Double,y:Double)

//使用了扩展,可以接收两个 double 和一个字符串。

//表示在构建的同时,把 x 和 y 交给父类进行构建。

class LabeledPoint(tag:string x:Double,y:Double) extends Point(x,y)

4、定义一个抽象类 shape,一个抽象方法 centerPoint(求出中心点),以及该抽象类的子类 Rectangle 和 Circle。为子类提供合适的构造器,并重写 enterPoint 方法。

解析:本题主要考察抽象类的使用。由于 Rectangle 和 Circle 没有给出具体的要求,所以从语法层面给出方法即可。

答案:

//抽象类

abstract class Shape{

//抽象方法

def centerPoint()

}

//定义了一个 Rectangle 类,Rectangle 类中有它的坐标。

//这里只给出了方法,内容是空着的。

class Rectangle(startX:Int,startY:Int,endX:Int,endY:Int) extends Shape{

def centerPoint(){}

}

// Circle 以及半径,内容也是空的。

class Circle(x:Int,y:Int,radius:Double) extends shape{

def centerPoint(){}

}

5、提供一个 Square 类,扩展自 java.awt.Rectangle 并且是三个构造器(考察点根据需求,写出不同的构造器):一个以给定的端点和宽度构造正方形,一个以(0,0)为端点和给定的宽度构造正方形,一个以(0,0)为端点,0为宽度构造正方形。

import java.awt.{Point, Rectangle}

class Square(point:Point,width:Int) extends Rectangle(point.x,point.y,width,width){

def this(){

this(new Point(0,0),0)

}

def this(width:Int){

this(new Point(0,0),width)

}

}

相关文章
|
消息中间件 存储 算法
嵌入式操作系统服务机制
嵌入式操作系统服务机制
398 0
|
Ubuntu 网络协议 Linux
【Linux】Android平板上远程连接Ubuntu服务器code-server进行代码开发
【Linux】Android平板上远程连接Ubuntu服务器code-server进行代码开发
320 0
|
前端开发 Java Maven
【前端学java】全网最详细的maven安装与IDEA集成教程!
【8月更文挑战第12天】全网最详细的maven安装与IDEA集成教程!
455 2
【前端学java】全网最详细的maven安装与IDEA集成教程!
|
存储 安全 数据安全/隐私保护
强密码策略之提高多账户安全性
【8月更文挑战第14天】
428 2
|
编解码 算法 计算机视觉
OpenCV(十七):拉普拉斯图像金字塔
OpenCV(十七):拉普拉斯图像金字塔
544 0
|
算法 搜索推荐 Java
太实用了!阿里内部强推的超全Java算法学习指南,已被彻底征服
算法和数据结构一直以来都是程序员的基本内功。 数据结构可以看作是算法实现的容器,通过一系列特殊结构的数据集合,能够将算法更为高效而可靠地执行起来。
|
监控 Java 调度
【JavaSE】多线程篇(五)线程专项练习题
文章目录 1 编程题 1.1 打印数字,读取通知 1.2 取钱问题 2 判断题 3 简答题
【JavaSE】多线程篇(五)线程专项练习题
|
存储 机器学习/深度学习 算法
《图解数据结构与算法》(Java代码实现、注释解析、算法分析)
数据结构可以简单的理解为数据与数据之间所存在的一些关系,数据的结构分为数据的存储结构和数据的逻辑结构。
441 0
《图解数据结构与算法》(Java代码实现、注释解析、算法分析)
|
API C++ Windows
C++命名规则&书写规范
C++命名规则&书写规范
1744 0