从零开始学Scala系列(六)之类(Classes)和对象(Objects)
来源:互联网 发布:java poi 下载excel 编辑:程序博客网 时间:2024/06/06 00:23
1. scala Classes类
scala中的类有以下几种元素(和java中的类有点类似):
类(class),属性(field),方法(method)
来个简单的例子
class Animal { val name: String = "jack" var age: Int = 1 def eat: Unit = println("eat...") override def toString: String = s"[name=$name, age=$age]"}object Main { def main(args: Array[String]): Unit = { val animal = new Animal println(animal.name + "::" + animal.age) println(animal) animal.eat }}
在上面的例子中 定义了一个Animal类,其中有两个属性 , 分别是val(相当于java中的final)类型的name 和var(普通变量)类型的age。还定义一个eat方法
当方法体内只有一行代码时,可以省略大括号{}, 重写了toString方法 scala中所有的类都有一个顶层父类scala.Any和java中的java.lang.Object类似。下面贴一下Any的源码
abstract class Any { def equals(that: Any): Boolean def hashCode(): Int def toString(): String final def getClass(): Class[_] = sys.error("getClass") final def ==(that: Any): Boolean = this equals that final def != (that: Any): Boolean = !(this == that) final def ##(): Int = sys.error("##") final def isInstanceOf[T0]: Boolean = sys.error("isInstanceOf") final def asInstanceOf[T0]: T0 = sys.error("asInstanceOf")}
scala中的类可以带上类参数使得代码更简洁 可以改写一下Animal的代码
class Animal(nameParam: String, ageParam: Int) { val name: String = nameParam var age: Int = ageParam def eat: Unit = println("eat...") override def toString: String = s"[name=$name, age=$age]"}object Main { def main(args: Array[String]): Unit = { val animal = new Animal("jack", 2) //val animal = new Animal(ageParam = 2, nameParam = "jack") 还可以指定参数名称赋值 很灵活 println(animal.name + "::" + animal.age) println(animal) animal.eat }}
当然类参数还可以有默认值 就是当不传该参数的时候使用默认值 如下
class Animal(nameParam: String = "jack", ageParam: Int) { val name: String = nameParam var age: Int = ageParam def eat: Unit = println("eat...") override def toString: String = s"[name=$name, age=$age]"}object Main { def main(args: Array[String]): Unit = { val animal = new Animal(ageParam = 2) //val animal = new Animal("rose", 2) println(animal.name + "::" + animal.age) println(animal) animal.eat }}
scala中还有一种单例对象,上面的object Main就是一个单例对象, scala中类还可以有一个伴生单例对象 而且它们彼此之间都可以相互访问自己的属性或方法 尽管可能是private的[说明: scala中没加修饰符的属性或方法都是public的], scala中的属性或方法都没有static类型的,要想定义此类型可在伴生对象中定义。如下代码所示:
class Animal(nameParam: String = "jack", ageParam: Int) { val name: String = nameParam var age: Int = ageParam def eat: Unit = println("eat...") override def toString: String = Animal.show(this)}object Animal { val color: String = "black" def sleep: Unit = println("sleep") def show(animal: Animal): String = s"[name=${animal.name}, age=${animal.age}]"}
上面的object Animal就是类Animal伴生的单例对象,其中定义的属性和方法都是static的
2. scala 修饰符(modifiers)
scala中的修饰有private, protected两种,未加修饰符的就是public范围的。
1,private只能在本类中访问和java中private差不多,但是不同的是scala中的外部类不能访问内部类的private修饰的属性或方法, 但是也有手段来实现想java中的private的效果。来看代码
class Outer { private val nameOuter = "outer" class Inner { private val nameInner = "inner" } //这里是无法编译通过的 报错 //Error:(27, 43) value nameInner in class Inner cannot be accessed in Outer.this.Inner def inner(inner: Inner): String = inner.nameInner }
使用private[Outer]指定修饰符范围:就是在Outer这个类的范围内就可以访问, 看代码:
class Outer { private val nameOuter = "outer" class Inner { private[Outer] val nameInner = "inner" } //达到了和java中一样的效果 很灵活 def inner(inner: Inner): String = inner.nameInner}
2, protected 修饰符
先来对比下scala和java中protected的范围
java中 protected修饰范围: 所有的子类和在同一包下的类
scala中 protected修饰范围: 所有子类
看来还是不同的 但是在scala中还是可以实现在java中的效果。
package pkg1 { class Super { protected val name = "super" } class Other { //这里是编译不能通过的 因为Other不是Super的子类 def show(su: Super): String = su.name }}package pkg2 { import pkg1._ class Sub extends Super { def show(su: Super): String = su.name }}
scala中不仅可以向java那样package在文件的头部, 也可以像上面的代码一样定义package
比如
package pkg1package pkg2{//这里代码都是定义在pkg1.pkg2包里的 都是可以叠加的}import pkg1._ scala中import可以在任何地方出现 _下划线相当于java中的*
好了 再次回到protected修饰符的问题上 如何在scala中实现protected在java中的效果,看代码
package pkg1 { class Super { //可以在包pkg1任何范围内访问 protected[pkg1] val name = "super" } class Other { //这里是编译不能通过的 因为Other不是Super的子类 def show(su: Super): String = su.name }}package pkg2 { import scala.date20170506.pkg1._ class Sub extends Super { def show(su: Super): String = su.name }}
现在来详细看看scala中的修饰符的范围定义问题 只能说非常灵活
private[X] val f = "f" X可以还是包名 类名 单例Object名 还可以是this
包对象 package object 所有包内类 对象均可以访问该对象定义的属性和方法
package object pkg1 { val name = "pkg1" def show: Unit = name}
- 从零开始学Scala系列(六)之类(Classes)和对象(Objects)
- 从零开始学Scala系列(六)之类(Classes)和对象(Objects)
- Scala之类和对象
- scala学习之类和对象
- scala基础之类和对象
- Classes and objects(类和对象)
- Classes and Objects :类和对象(1)
- Classes and Objects :类和对象(2)
- 从零开始学Scala系列(二)之初识Scala
- 从零开始学Scala系列(二)之初识Scala
- 从零开始学Scala系列(五)之集合2--Set和Map
- 从零开始学Scala系列(五)之集合2--Set和Map
- 02-03.类和对象 Classes and Objects
- 一步一步学java之类和对象
- 从零开始学Scala系列(三)之初识循环分支结构
- 从零开始学Scala系列(四)之数组集合1
- 从零开始学Scala系列(三)之初识循环分支结构
- 从零开始学Scala系列(四)之数组集合1
- UTF-8基础
- 第1章事件
- 为什么要使用面向接口编程
- Linux命令源代码阅读whoami
- express框架应用
- 从零开始学Scala系列(六)之类(Classes)和对象(Objects)
- 第2章DOM概述
- UVA 1585
- 移植不同类型的STM32时候报错,parsing restarts here after previous syntax error
- 人生感言
- 1019. 数字黑洞 (20)
- GRUB2编译
- 新博客地址:akirakiwi.github.io
- 03.31 Linux定时任务