章节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$$
$Lambda1/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 funcB1 () {
while ( true ) {
. MODULE . println ( "funcB...." );
}
}
62.惰性函数(选修)
当函数返回值被声明为 lazy 时,函数的执行将被推迟,直到我
们首次对此取值,该函数才会执行。这种函数我们称之为惰性函
数。
}
}
public void main ( final String [] args ) {
this . funcB$1 ();
}
private final void funcB1 () {
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" )
}