一:包和引入
这一章暂时没有发现什么有用的,大家直接使用java中package的方法即可。此处只是为了文章的完整性。大佬们可以直接看第二章
包
书上讲的太局限了。个人感觉就是你在的类前面加上package就行了
package com.test.aa.bb
object FastLearnScala{
def main(args: Array[String]): Unit = {
println("aa")
}
}
作用域规则
1.一个子包可以直接访问父包的内容。
2.如果有人用scala已经命名的类作为自己的类,那就可以使用 new _root_.scala.collection.mutable.ArrayBuffer[String]来绝对路径访问包
(但是真正在使用过程中:1.大家默认导包的时候都是全路径 2.很少有人使用scala已经命名的包作为作为包名)
串联式包语句
package com.test.aa.bb{
//此时,com.test.aa里面的包,在此都不可见
package dd{
}
}
文件顶部标记法
package com.test.aa.bb
object FastLearnScala{
def main(args: Array[String]): Unit = {
println("aa")
}
}
这种方法是最常见的,也是使用最多的
包对象
package com.test.aa
package object bb{ //每一个package也可以定义一个对象,封装一些参数什么的
val aa = 10
}
package bb{
object FastLearnScala{
def main(args: Array[String]): Unit = {
aa //可以在类中直接访问
}
}
}
包可见性
package com.test
package aa{
object Learn{
private [aa] def cc(): Unit = {//只有aa包下面的类才可以访问这个方法
println("cc.FastLearnScala")
}
}
}
package bb{
object FastLearnScala{
def main(args: Array[String]): Unit = {
val learn = com.test.aa.Learn
learn.cc() //方法会报错
}
}
}
引入
import scala.collection.mutable.Map //导入类
import scala.collection.mutable._ //如果嫌麻烦,也可以通过这种方法来导包,一次性导入所有类
任何地方都可以声明引入
object FastLearnScala{
def main(args: Array[String]): Unit = {
import scala.collection.mutable.Map //在此导入所需要的类,可以进最大的可能减少类冲突
println("aa")
}
}
重命名和隐藏方法
import scala.collection.mutable.{Map,HashMap}//这种方法可以减少前面相同包层次的书写,真正使用也比较多
import scala.collection.mutable.{Map=>scalaMutableMap} //可以改变类的名称,在后面使用的过程中使用scalaMutableMap
import scala.collection.mutable.{Map=>_} //这种将Map隐藏起来,不进行导入操作
隐士引入
import java.lang._
import scala._
import Predef._
//scala程序默认将以上三个包导入的,scala会默认覆盖一些java的类
import collection.mutable.{Map=>scalaMutableMap}
import scala.collection.mutable.{Map=>scalaMutableMap} //两种写法本质上市没有区别的,个人比较老古董,还是喜欢上面的
二:继承
扩展类
class Persion(){
final val salary =0.0
final def aa(){}
}
class Employee extends Persion{
val salary =0.0 //会报错,因为父类中为final
def aa(){} //会报错,因为父类中为final
}
//和java中基本一致使用extends关键字,将字段或者方法定义为final就不可以在子类中重写
重写方法
class Persion(){
val salary =10
def mm(){
println("Persion method aa")
}
}
class Employee extends Persion{
override val salary =100
override def mm(){
super.mm()
}
}
//重写方法、变量和java一样就是 override ,如果需要调用父类的方法可以使用super
类型检查和转换
isInstanceOf方法的使用。
在java中都建议使用多态,在此就不写了
受保护字段和方法
前面介绍了private[this]方法,这是一个protect[this]方法,具体用法和private[this]一致,只是作用域不同
超类的构造
class Persion(salary:Int){
def mm(){
println("Persion method aa " +salary)
}
}
class Employee(name:String,salary:Int) extends Persion(salary:Int){
override def mm(){
super.mm()
}
}
//可以在子类的构造方法上构造父类的对象,如果父类有不同的参数名称就不行了
重写字段
class Persion(){
def salary = 10
}
class Employee() extends Persion(){
override val salary = 20
}
在父类中定义的数据可以在子类中进行覆盖。但是scala只有def,val,var三种类型,具体继承关系如下:
类型 | 继承后可选类型 |
def | def、val |
val | val |
var | var |
匿名子类
class Persion(){}
object FastLearnScala{
def main(args: Array[String]): Unit = {
val aa = new Persion(){ //此种定义的方法是定义一个新的类型
def greeting = "my name is Fred"
}
println(aa.greeting)
}
}
抽象类
abstract class dog(){
def id() = {}
}
class Persion extends dog(){
override def id() = { println(100)}
}
//这些内容前面已经介绍过,在此不在此说了
抽象字段
abstract class dog(){
val id = 1//var的变量不需要override 因为可以直接使用,废话了
}
class Persion extends dog(){
override val id = 100
}
构造顺序和提前定义
class dog(){
val id = 1
val array = Array[Int](id)
}
class Persion extends dog(){
override val id = 10
}
本来是想将10传递进数组的,但是由于父类的初始化早于子类,导致初始化的数字是1
class dog(){
val id = 1
val array = Array[Int](id)
}
class Persion extends{
override val id = 10
} with dog
这种写法个人感觉是Persion是将{}里面的内容作为一个对象继承同事继承了dog,因为scala从左往右依次继承所以最终的结果是10
scala继承层级
第一层级 | Any | |
第二层级 | AnyVal | AnyRef |
第三层级 | 八种基本类型的unit |
scala class(scala Object) 和java class |
对象相等性
AnyRef的eq方式检查的是两个引用是否是指向同一个对象,而AnyRef的equals方法调用的eq方法,当你实现类的时候应该考虑的是重新写equals方法
对于Array方法而言他就没有重新写等于方法,所有可选的比较都是false
val dog = Array[String]("a")
val dog1 = Array[String]("a")
println(dog.eq(dog1))
println(dog.equals(dog1))
println(dog == dog1)