章节3基础功能搭建
46.函数作为值三
package
cn
.
itbaizhan
.
chapter03
//
函数作为值,函数也是个对象
object
FunctionToTypeValue
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//Student stu = new Student()
/*val a = ()=>{"GTJin"}
//
输出对象的地址
//cn.itbaizhan.chapter03.FunctionToTypeValue$$
$Lambda$1/495053715@3f0ee7cb
println(a)*/
//
完整写法
def
funcA
():
String
=
{
println
(
"funcA
被执行了。。。
"
)
"GTJin"
}
73
/*println("--------before val x = funcA()--
--------")
//
执行下一行代码,输出:
funcA
被执行了。。。 表示将
函数
funcA
的结果赋值给了
x
,并不是将
funcA
作为对象赋值给
x
val x = funcA()
println(x)
println("--------after val x = funcA()-----
-----")*/
//
如果想将
funcA
函数作为对象赋值给
x
,那么该如何实
现?
//
使用
"
函数名
+
空格
+ _",
将函数作为对象赋值给
x
,在赋值的过程中不会函数体中的代码
val
x
=
funcA
_
//
写下
x
后提示框显示
"x ()=>String",
表示
x
是一
个无参返回值类型为
String
的函数
//
万物皆对象,是对象就应该有对应的类型,所以函数也
有对象的类型
//Function0[String] Function0
表示
0
个参数的函
数对象
[String]
表示函数的返回值类型为
String
//Function1[-T1,+R]
表示
1
个参数的函数对象
[]
里
面最后的
+R
表示返回值类型为,
-T1
参数类型
//Function2[-T1,-T2,+R]
表示
2
个参数的函数对象
[]
里面最后的
+R
表示返回值类型,
-T1
第一参数类型
-T2
第二
个参数类型
//... Function22
将函数作为对象赋值时,参数声明
的个数最多
22
个,对应
Function22
//
函数独立定义和使用时,声明参数的个数时没有限制
的。、
//22
在
Scala
语言中是一个神奇的数字,官方没有明确说
明,后续还会在其它地方见到
Tuple22
val
f1
:
Function0
[
String
]
=
funcA
_
println
(
x
==
f1
)
//false
相当于创建了两个函数对象
74
def
funcB
(
name
:
String
):
String
=
{
"funcB....name="
+
name
}
//
函数类型还有另外一种表示方式:
(
参数类型
)=>
返回值
类型 ,多个参数之间使用逗号隔开
//val f2:Function1[String,String] = funcB
_
val
f2
:(
String
)
=>
String
=
funcB
_
//
如果函数只有一个参数小括号可以省略
val
f2_1
:
String
=>
String
=
funcB
_
def
funcC
(
name
:
String
,
age
:
Int
):
String
=
{
s
"name=${name},age=${age}"
}
//
两个或两个以上参数时,小括号不能省略
val
f3
:(
String
,
Int
)
=>
String
=
funcC
_
//val f3_1:String,Int=>String = funcC _ //
错误的
/**val x = funcA _
为什么在函数名后 使用下滑线让
函数作为对象使用,因为代码中没有明确的变量
*
类型,所以需要通过取值类型进行推断。
*
如果变量声明时的类型为函数类型,那么可以不适用下
划线让函数作为对象
*
*/
val
f4
:(
String
)
=>
String
=
funcB
val
f5
:(
String
,
Int
)
=>
String
=
funcC
}
}
47.函数作为值四
实时效果反馈
1.
关于
Scala
函数作为值的描述,错误的是:
A
函数类型表示方式:
(
参数类型
) =>
返回类型 注:多个参数
的话之间逗号隔开。
B
如果在声明时并没有指定具体的函数类型,那么下划线不能
省略。
C
如果变量声明的类型为函数类型,那么可以不使用下划线让
函数作为对象。
D
将函数作为对象赋值时,参数声明的个数没有限制。
答案:
1=>D
将函数作为对象赋值时,参数声明的个数最多
22
个,对
应
Function22
。
48.函数作为参数_无参无返回值
object
FunctionToTypeArgXx
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
(
x
:
Int
,
y
:
Int
,
函数
):
Unit
=
{
val
result
=
函数
(
x
,
y
)
println
(
result
)
}
funcA
(
1
,
2
,
求和函数
)
funcA
(
1
,
2
,
求差函数
)
}
}
76
代码拆解分析演示:
package
com
.
itbaizhan
.
chapter03
//
函数作为参数
object
FunctionToTypeArg1
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//TODO 1
无参无返回值
/**public void method(Student stu){}
* public void method(
参数类型 参数名称
){}
* Scala
同理,让函数作为参数
* fun:()=>Unit
表示参数是一个函数对象,这个函数
是一个无参无返回值的函数
* ()
表示是一个无参的函数
* Unit
表示是一个无返回值的函数
*/
def
funcA
(
fun
:()
=>
Unit
):
Unit
=
{
//
调用传递过来的函数
fun
()
}
def
funcObjA
():
Unit
=
{
println
(
"funcObjA
被调用
"
)
}
//funcA(funcObjA _)
//
下划线可以省略
应该在函数
funcA
声明的时候定义了
参数的函数类型
无参无返回值的类型
//funcA(funcObjA)
// TODO 2
有参数以后返回值
/**fun:(Int,Int)=>Int)
表示
funcB
的参数为一个函
数
* (Int,Int)
这个函数是一个有两个参数的函数,这两
个参数都是
Int
类型
* Int
表示这个函数的返回值是一个
Int
类型
77
* @param fun
*/
def
funcB
(
fun
:(
Int
,
Int
)
=>
Int
):
Unit
=
{
//
该设计缺陷是
fun(2,1)
写死的参数值
val
result
=
fun
(
2
,
1
)
println
(
result
)
}
//
定义一个函数
def
funcObjB1
(
x
:
Int
,
y
:
Int
):
Int
=
{
x
+
y
}
//funcB(funcObjA) //
错误的,因为
funcObjA
参数和
返回值类型
与
funcB
要求的参数类型不匹配
funcB
(
funcObjB1
)
//3
def
funcObjB2
(
x
:
Int
,
y
:
Int
):
Int
=
{
x
-
y
}
funcB
(
funcObjB2
)
//1
def
funcObjB3
(
x
:
Int
,
y
:
Int
):
Int
=
{
x
/
y
}
funcB
(
funcObjB3
)
//2
//TODO 3.
省略 作为参数的函数
//
省略关键字、函数名、返回值类型
;
在将
": ="
改为
"=>"
funcB
((
x
:
Int
,
y
:
Int
)
=>
{
x
/
y
})
//
继续简化: 函数体只有一行,函数体外的
{}
可以省略
funcB
((
x
:
Int
,
y
:
Int
)
=>
x
/
y
)
//
参数的类型如果能够推断出来,参数的类型可以省略
78
参数函数简化案例一,一个参数无返回值:
funcB
((
x
,
y
)
=>
x
/
y
)
//
如果参数只有一个的话,参数列表的小括号可以省略
//funcB(x,y=> x/y)
错误的 参数
>=2
话,参数列表的
小括号不可以省略
//
如果参数在使用时,按照声明的顺序只使用一次时,那
么可以使用下划线代替
println
(
"------------funcObjBn
不需要定义
-----
------------"
)
funcB
((
_
/
_
))
//2
继续省略
funcB
(
_
/
_
)
//2
funcB
(
_
-
_
)
//1
funcB
(
_
*
_
)
//2
funcB
(
_
+
_
)
//3
}
}
49.函数作为参数_有参有返回值
一个参数无返回值:
funcB
((
x
,
y
)
=>
x
/
y
)
//
如果参数只有一个的话,参数列表的小括号可以省略
//funcB(x,y=> x/y)
错误的 参数
>=2
话,参数列表的
小括号不可以省略
//
如果参数在使用时,按照声明的顺序只使用一次时,那
么可以使用下划线代替
println
(
"------------funcObjBn
不需要定义
-----
------------"
)
funcB
((
_
/
_
))
//2
继续省略
funcB
(
_
/
_
)
//2
funcB
(
_
-
_
)
//1
funcB
(
_
*
_
)
//2
funcB
(
_
+
_
)
//3
}
}
package
com
.
itbaizhan
.
chapter03
object
FunctionToTypeArg2
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
(
fun
:(
String
)
=>
Unit
):
Unit
=
{
fun
(
"GTJin"
)
}
def
funArg
(
name
:
String
):
Unit
=
{
println
(
name
)
}
funcA
(
funArg
)
//
如果函数
funArg
只是被调用一次,可以进行简化
//
首先省略
def
、函数名、返回值类型
funcA
(
(
name
:
String
)
=>
{
println
(
name
)
79
参数函数简化案例二,两个参数有返回值:
})
//
函数体只有一行省略大括号
funcA
(
(
name
:
String
)
=>
println
(
name
)
)
//
参数类型可以推导出来,也可以省略
funcA
(
(
name
)
=>
println
(
name
)
)
//
只有一个参数,小括号也可以省略
funcA
(
name
=>
println
(
name
)
)
//
还可以继续省略,以后在
spark
的代码中会遇到类似的
用法
funcA
(
println
(
_
))
//
匿名函数的至简原则的最简化版
本
funcA
(
println
)
//
该方式调用的不再是匿名函数的简化
版了,而是调用
println
函数
//funcA(funArg)
}
}
50.函数作为参数_有参有返回值简化演示
package
com
.
itbaizhan
.
chapter03
object
FunctionToTypeArg3
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
(
fun
:(
Double
,
Double
)
=>
Double
):
Double
=
{
fun
(
1.0
,
2.0
)
}
80
参数函数简化案例三:
def
funcB
(
x
:
Double
,
y
:
Double
):
Double
=
{
x
/
y
}
funcA
(
funcB
)
//
简化函数
funcA
(
(
x
:
Double
,
y
:
Double
)
=>
{
x
/
y
}
)
funcA
(
(
x
,
y
)
=>
{
x
/
y
}
)
funcA
(
(
x
,
y
)
=>
x
/
y
)
//
顺序使用且只用一次可以简化为下划线
println
(
funcA
(
_
/
_
))
//0.5
//
但是如果不是顺序使用,无法使用下划线简化,比如:
结果为
2
不是
0.5
println
(
funcA
(
(
x
,
y
)
=>
y
/
x
)
)
}
}
51.函数作为参数_一参无返回值简化演示
package
com
.
itbaizhan
.
chapter03
81
3.6.3
函数作为返回值
//
函数作为参数的常见场景
object
FunctionToTypeArg4
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
(
x
:
Int
,
y
:
Int
,
fun
:(
Int
,
Int
)
=>
Int
):
Unit
=
{
val
result
=
fun
(
x
,
y
)
println
(
result
)
}
funcA
(
1
,
2
,
(
x
:
Int
,
y
:
Int
)
=>
x
+
y
)
funcA
(
1
,
2
,
(
x
,
y
)
=>
x
+
y
)
funcA
(
1
,
2
,
_
+
_
)
funcA
(
1
,
2
,
_
-
_
)
funcA
(
1
,
2
,
_
*
_
)
funcA
(
1
,
2
,
_
/
_
)
}
}
52.函数作为参数_两参有返回值简化演示
3.6.3
函数作为返回值
//
函数作为参数的常见场景
object
FunctionToTypeArg4
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
(
x
:
Int
,
y
:
Int
,
fun
:(
Int
,
Int
)
=>
Int
):
Unit
=
{
val
result
=
fun
(
x
,
y
)
println
(
result
)
}
funcA
(
1
,
2
,
(
x
:
Int
,
y
:
Int
)
=>
x
+
y
)
funcA
(
1
,
2
,
(
x
,
y
)
=>
x
+
y
)
funcA
(
1
,
2
,
_
+
_
)
funcA
(
1
,
2
,
_
-
_
)
funcA
(
1
,
2
,
_
*
_
)
funcA
(
1
,
2
,
_
/
_
)
}
}
package
com
.
itbaizhan
.
chapter03
//
函数作为函数的返回值
object
FunctionToFunResult
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//TODO 1.
对比
Java
代码
/**public Student getStudent(){
* return new Student();
* }
*
返回的是一个对象,而在
Scala
中函数也是一个对象,
82
为何不直接调用
resultFun()?
*
所以也可以使用一个函数作为另外一个函数的返回值
*/
def
resultFun
():
Unit
=
{
println
(
"resultFun...."
)
}
def
funcA
(): ()
=>
Unit
=
{
//
写上函数的类型
()=>Unit
resultFun
_
//
返回的是函数对象
}
val
f1
=
funcA
_
//f2
就是
resultFun
val
f2
=
f1
()
//
调用
f2
f2
()
//
简化以上调用
以后的代码中经常遇到
funcA
()()
//
上行代码等价于
resultFun(),
那么为何不直接调用
呢?
}
}
53.函数作为参数_案例三
54.函数作为返回值一
55.函数作为返回值二
package
com
.
itbaizhan
.
chapter03
object
FunctionToFunResult2
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//TODO 2.
将函数作为返回值返回,一般应用在将内部的
函数在外部使用
/*def outer(): ()=>Unit ={
def inner():Unit={
println("inner.....")
}
inner _
}
outer()()*/
//TODO 3.
如果层次多了,就比较麻烦了,这种方式不推
荐自定义开发中使用
def
outer
(): ()
=>
()
=>
Unit
=
{
def
mid
(): ()
=>
Unit
=
{
def
inner
():
Unit
=
{
println
(
"inner....."
)
}
inner
_
}
mid
_
}
outer
()()()
}
}
56.闭包
package
com
.
itbaizhan
.
chapter03
//
闭包
object
FunctionClosure
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
outer
(
x
:
Int
): (
Int
)
=>
Int
=
{
def
inner
(
y
:
Int
):
Int
=
{
x
+
y
}
inner
_
}
//println(outer(2)(3))
val
fun
=
outer
(
2
)
84
由于在执行
inner
的时候,
outer
已经出栈了,所以变量
x
已经不
存在,那么在
inner
中该如何进行计算呢,底层又是如何实现的呢?
反编译:选择
target/classes/com/itbaizhan/chapter03/FunctionClosure->
右
键
->Decompile Scala to Java
val
fun2
=
fun
(
3
)
println
(
fun2
)
}
}
57.匿名函数
package
com
.
itbaizhan
.
chapter03
//
匿名函数
object
FunctionNoName
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
(
fun
:
Int
=>
Int
):
Int
=
{
fun
(
3
)
}
//
使用匿名函数作为参数
println
(
funcA
((
x
:
Int
)
=>
{
x
*
5
}))
//
类型可以推导出来所以可以省略
println
(
funcA
((
x
)
=>
{
x
*
5
}))
//
只有一个参数小括号可以省略
println
(
funcA
(
x
=>
{
x
*
5
}))
//
函数体只有一行,
{}
可以省略
println
(
funcA
(
x
=>
x
*
5
))
//
使用
_
进行简化
println
(
funcA
(
_
*
5
))
//
在
funcA
内部使用
fun(3)
不够灵活,再次进行完善
def
funcB
(
x
:
Int
,
fun
:
Int
=>
Int
):
Int
=
{
fun
(
x
)
}
println
(
funcB
(
4
,
_
*
2
))
//8
println
(
funcB
(
4
,
_
+
2
))
//6
}
}
58.控制抽象
package
com
.
itbaizhan
.
chapter03
import
scala
.
util
.
control
.
Breaks
//
函数控制抽象
object
FunctionControlAbstract
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//TODO 1.
对比匿名函数方式
//
函数类型:
()=>Unit
def
funcA
(
opt
: ()
=>
Unit
):
Unit
=
{
opt
()
}
funcA
{
()
=>
{
println
(
"
函数控制抽象入门
"
)
}
}
//TODO 2.
函数控制抽象
//
参数类型不完整,在传递参数时也是不完整的;只传递
代码就可以了,不需要完整的声明。
def
funcB
(
opt
:
=>
Unit
):
Unit
=
{
opt
}
funcB
{
println
(
"
函数控制抽象入门
"
)
}
//TODO 3.
可以通过控制抽象设计语法
Breaks
.
breakable
{
for
(
index
<-
1
to
5
){
if
(
index
==
3
){
Breaks
.
break
()
89
3.10
柯里化函数
柯里化是一个数学家
Curry
的音译。
将无关的参数分离开,提高函数效率。
}
println
(
"index="
+
index
)
}
}
}
}
59.柯里化函数
柯里化是一个数学家
Curry
的音译。
将无关的参数分离开,提高函数效率。
}
println
(
"index="
+
index
)
}
}
}
}
package
com
.
itbaizhan
.
chapter03
//
柯里化函数
object
FunctionCurry
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
def
funcA
():
Int
=
{
var
result
:
Int
=
1
for
(
i
<-
1
to
10
){
result
=
i
Thread
.
sleep
(
10
)
}
result
}
def
funcB
():
Int
=
{
var
result
:
Int
=
1
for
(
i
<-
1
to
20
){
result
=
i
Thread
.
sleep
(
10
)
}
result
90
运行输出:
用时几乎缩减百分之五十。
}
def
funcC
(
a
:
Int
,
b
:
Int
):
Int
=
{
a
+
b
}
def
funcD
(
a
:
Int
)(
b
:
Int
):
Int
=
{
a
+
b
}
val
start1
:
Long
=
System
.
currentTimeMillis
()
println
(
funcC
(
funcA
(),
funcB
()))
val
end1
:
Long
=
System
.
currentTimeMillis
()
println
(
"------------
未使用柯里化用时
:"
+
(
end1
-
start1
))
val
start2
:
Long
=
System
.
currentTimeMillis
()
println
(
funcD
(
funcA
())(
funcB
()))
val
end2
:
Long
=
System
.
currentTimeMillis
()
println
(
"------------
使用柯里化用时
:"
+
(
end2
-
start2
))
}
}
30
------------
未使用柯里化用时
:695
30
------------
使用柯里化用时
:328
60.递归函数
package
com
.
itbaizhan
.
chapter03
//
递归函数
object
FunctionRecursion
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//TODO 1.
递归函数
/**
递归函数:在函数内部调用函数本身
*
注意:
* 1.scala
中要求递归函数必须明确声明返回值类型
* 2.
递归函数一定要有跳出的出口
* 3.
传递的参数之间存在某种关系时才可以设计成递归函
数
* @param num
* @return
*/
def
funcA
(
num
:
Int
):
Int
=
{
if
(
num
==
1
)
//
跳出的出口
num
else
num
*
funcA
(
num
-
1
)
}
print
(
funcA
(
5
))
}
}
61.尾递归函数(选修)
tail recursion
义译为尾递归,或伪递归。
package
com
.
itbaizhan
.
chapter03
import
scala
.
annotation
.
tailrec
//
尾
(
伪
)
递归函数
object
FunctionRecursion2
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
/*def funcA(): Unit = {//
funcA()
println("funcA....")
}
funcA()*/
def
funcB
():
Unit
=
{
println
(
"funcB...."
)
funcB
()
}
funcB
()
93
Scala
中的尾递归被编译器优化为了
while
循环,所以应该理解
成为伪递归。
3.12
惰性函数
(
选学
)
当函数返回值被声明为
lazy
时,函数的执行将被推迟,直到我
们首次对此取值,该函数才会执行。这种函数我们称之为惰性函
数。
}
}
public
void
main
(
final
String
[]
args
) {
this
.
funcB$1
();
}
private final
void
funcB$1
() {
while
(
true
) {
.
MODULE$
.
println
(
"funcB...."
);
}
}
62.惰性函数(选修)
当函数返回值被声明为
lazy
时,函数的执行将被推迟,直到我
们首次对此取值,该函数才会执行。这种函数我们称之为惰性函
数。
}
}
public
void
main
(
final
String
[]
args
) {
this
.
funcB$1
();
}
private final
void
funcB$1
() {
while
(
true
) {
.
MODULE$
.
println
(
"funcB...."
);
}
}
package
com
.
itbaizhan
.
chapter03
//
惰性函数
object
FunctionLazy
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//
函数结果没有使用,则函数不执行;直到使用结果才执
行。
def
funcA
():
String
=
{
println
(
"funcA
被执行了
......"
)
"
天王盖地虎
"
}
//
当函数返回值被声明为
lazy
时,函数的执行将被推迟,
直到我们首次对此取值
,
该函数才会被执行。
94
输出结果如下:
lazy val
password
=
funcA
()
println
(
"----------------"
)
println
(
password
)
//
首次对此取值
println
(
"================"
)
}
}
----------------
funcA
被执行了
......
天王盖地虎
章节4面向对象基础
63.面向对象基础概述
Scala
是一门完全面向对象的语言,摒弃了
Java
中很多不是面向
对象的语法。虽然如此,但其面向对象思想和
Java
的面向对象思想
还是一致的。
//
包声明
package
com
.
itbaizhan
.
chapter04
//
类定义
class
Point
(
xc
:
Int
,
yc
:
Int
) {
//
属性
var
x
:
Int
=
xc
var
y
:
Int
=
yc
//
方法
def
move
(
dx
:
Int
,
dy
:
Int
) {
x
=
x
+
dx
y
=
y
+
dy
95
面向对象基础包含:包
package
、导入
import
、类、属性、访
问权限、方法、对象、构造方法等。
64.面向对象基础_包package
Scala
中基本的
package
包语法和
Java
完全一致,就是在代码的
最后不加
";"
。
println
(
"x
的坐标点
: "
+
x
);
println
(
"y
的坐标点
: "
+
y
);
}
}
object
ObjectAndClass
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
//
实例化对象
val
point
=
new
Point
(
10
,
20
);
//
移到一个新的位置
point
.
move
(
10
,
10
);
}
}
package
com
.
itbaizhan
.
chapter04
object
PackageDemo
{
}
96
Java
中
package
包的语法比较单一,
Scala
对此进行如下扩展:
1
Scala
中的包和类的物理路径没有关系
2
package
关键字可以嵌套声明使用
3
同一个源码文件中子包可以直接访问父包中的内容,而无需
import
//package com.itbaizhan.chapter04
package
com
package
itbaizhan
//package chapter04
package
chapter05
object
PackageDemo
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
println
(
"package.."
)
}
}
//package com.itbaizhan.chapter04
package
com
package
itbaizhan
{
class
Person
{
def
showInfo
():
Unit
=
{
println
(
"showInfo..."
)
}
}
package
chapter04
{
object
PackageDemo
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
new
Person
().
showInfo
()
}
97
4
Scala
中
package
也可以看作对象,并声明属性和函数
在
PackageDemo
的
main
方法中可以直接调用
showMe()
实时效果反馈
1.
关于
Scala
包的描述,错误的是:
A
Scala
中基本的
package
包语法和
Java
完全一致,就是在代码
的最后不加
";"
。
B
package
关键字不可以嵌套声明使用。
C
Scala
中
package
也可以看作对象,并声明属性和函数。
D
同一个源码文件中子包可以直接访问父包中的内容,而无需
import
。
答案:
1=>B package
关键字可以嵌套声明使用。
65.面向对象基础_类
66.面向对象基础_java中的导入
67.面向对象基础_Scala中的导入Import一
68.面向对象基础_Scala中的导入Import二
//TODO 6.scala
导入类的操作,是以相对路径
(
当前所在
包的路径
)
的方式导入的
//
如果想使用绝对路径的方式,需要在包名前添加:
_root_.
/* val hashMap = new java.util.HashMap[Int,
String]()
hashMap.put(1,"tuhao")
hashMap.put(2,"baifumei")
println(hashMap)//{1=tuhao, 2=baifumei}*/
//println(new
java.util.HashMap())//com.itbaizhan.chapter04.j
ava.util.HashMap@2ff4f00f
//println(new
_root_.java.util.HashMap())//{}
表示使用了
jdk
的
HashMap
//TODO 7.Scala
中可以给导入的类起别名,简化使用
import
java
.
util
.{
ArrayList
=>
AList
}
println
(
new
AList
())
}
}
/*package java{
package util{
class HashMap{
}
}
}*/
103
B
实时效果反馈
1.
关于
Scala Import
使用的描述,错误的是:
A
星号在
scala
中有特殊的用途,不能使用在
import
语句中,
需要使用
_
来代替
*
。
import
导入语句只能用在
package
语句和
class
定义之间。
C
Scala
中可以给导入的类起别名,简化使用。
D
可以在一行中导入一个包中的多个类
,
简化代码。
答案:
1=>B import
导入语句可以在任意地方使用
69.面向对象基础_属性一
package
com
.
itbaizhan
.
chapter04
import
scala
.
beans
.
BeanProperty
class
Animal
{
//
属性声明,
java
中可以不赋值,
scala
中属性必须显示地
初始化
//var name:String //
抛错
//
可以直接赋予一个默认值
//var name:String = "
华南虎
"
//
如果希望像
java
一样可以由系统进行初始化,后续手动调
用
setter
赋值,声明时使用
_
赋值
var
name
:
String
=
_
//
使用
val
声明的属性,编译器将之编译为私有的属性,并使
用
final
修饰,不可修改,
//
所以只提供的
get
方法,而没有提供
set
方法
val
age
:
Int
=
30
//
属性声明时如果使用
private
修饰,编译器将该属性对应
的
get
和
set
方法也是编译为私有化的方法
104
实时效果反馈
1.
关于
Scala
属性的描述,错误的是:
A
var
声明的属性编译器将之编译为类的私有属性,通过提供
getter
和
seter
方法。
B
使用
val
声明的属性,编译器将之编译为私有的属性,并使
用
final
修饰,不可修改。
private var
color
:
String
=
_
//
通过查看
Animal
类的源码,属性的
get
和
set
方法不符合
bean
规范
//
如果想符合
bean
规范
(id=>getId,setId)
,需要在属性
声明前加上
@BeanProperty
@BeanProperty
var
kind
:
String
=
_
}
object
ClassField
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
val
animal
=
new
Animal
()
//var
声明的属性编译器将之编译为类的私有属性,通过提
供
getter
和
seter
方法
//
如下方式赋值相当于调用的
animal.setName("
东北
虎
")
animal
.
name
=
"
东北虎
"
//
访问类的属性时相当于调用了对象的
get
方法
println
(
animal
.
name
)
//val
声明的属性被
final
修饰,并未提供
set
方法,所以
不可改变
//animal.age = 10
}
}
实时效果反馈
1.
关于
Scala
属性的描述,错误的是:
A
var
声明的属性编译器将之编译为类的私有属性,通过提供
getter
和
seter
方法。
B
使用
val
声明的属性,编译器将之编译为私有的属性,并使
用
final
修饰,不可修改。
private var
color
:
String
=
_
//
通过查看
Animal
类的源码,属性的
get
和
set
方法不符合
bean
规范
//
如果想符合
bean
规范
(id=>getId,setId)
,需要在属性
声明前加上
@BeanProperty
@BeanProperty
var
kind
:
String
=
_
}
object
ClassField
{
def
main
(
args
:
Array
[
String
]):
Unit
=
{
val
animal
=
new
Animal
()
//var
声明的属性编译器将之编译为类的私有属性,通过提
供
getter
和
seter
方法
//
如下方式赋值相当于调用的
animal.setName("
东北
虎
")
animal
.
name
=
"
东北虎
"
//
访问类的属性时相当于调用了对象的
get
方法
println
(
animal
.
name
)
//val
声明的属性被
final
修饰,并未提供
set
方法,所以
不可改变
//animal.age = 10
}
}
105
访问权限
有效范围
private
当前类中
默认缺省
当前类中、本包
(
以及当前类所在的当前包中
)
。
protected
当前类中、本包、当前类的子类中
public
任意位置
访问权限
有效范围
private
当前类中
private
【包名】
当前类中、本包的类中(包私有)
protected
当前类中、子类中
默认缺省
表示公共的,
scala
中没有
public
关键字
C
如果想属性的
set
和
get
方法符合
bean
规范
(id=>getId,setId)
,需要在属性声明前加上
@BeanProperty
。
D
属性声明时是否使用
private
修饰,编译器对属性编译时都
是做一样的处理
答案:
1=>D
不一样处理,使用
private
修饰的属性的
get
和
set
方法也
会被私有化;不使用
private
修饰的属性的
get
和
set
方法是公共的。
70.面向对象基础_属性二
71.面向对象基础_访问权限
72.面向对象基础_方法
73.面向对象基础_对象
74.面向对象基础_构造方法
章节5面向对象高级
75.伴生类和伴生对象一
76.伴生类和伴生对象二
77.伴生类和伴生对象三
78.抽象类和抽象方法一
79.抽象类和抽象方法二
80.抽象属性一
81.抽象属性二
82.Trait_Java中的接口
83.Trait_基本使用一
84.Trait_基本使用二
85.Trait_作用解耦合
86.Trait_原理
87.Trait_初始化叠加一
88.Trait_初始化叠加二
89.Trait_功能叠加
90.Trait_反射一
91.Trait_反射二
92.多学三招_枚举类
93.多学三招_应用类
94.多学三招_type定义新类型
package
com
.
itbaizhan
.
chapter05
object
TypeDemo
extends
App
{
//TODO 1.scala
源码
//
将
java.lang.String
定义为
String
类
//type String = java.lang.String
//
将
java.lang.Class[T]
定义为
Class[T]
类
//type Class[T] = java.lang.Class[T]
//
使用
type
关键字可以定义新的数据数据类型名称,本质上
就是类型的一个别名
type
KIntVStrMap
=
java
.
util
.
HashMap
[
Int
,
String
]
private val
map
=
new
KIntVStrMap
()
map
.
put
(
1
,
"java"
)
//
提示
key
为
Int
类型,
value
为
String
类型
map
.
put
(
2
,
"scala"
)
}