包
一.包嵌套
( 1)一个源文件中可以声明多个 package
( 2)子包中的类可以直接访问父包中的内容,而无需导包
( 3)包对象:在 Scala 中可以为每个包定义一个同名的包对象, 定义在包对象中的成员, 作为其对
应包下所有 class 和 object 的共享变量, 可以被直接访问。
( 4)导包说明
类
(1)scala里的setget: @BeanPropetry
class Person {
var name: String = "bobo" //定义属性
var age: Int = _ // _表示给属性一个默认值
//Bean 属性( @BeanProperty)
@BeanProperty var sex: String = "男"
//val 修饰的属性不能赋默认值,必须显示指定
}
封装
一.概念
Scala 中的 public 属性,底层实际为 private,并通过 get 方法( obj.field())和 set 方法
( obj.field_=(value))对其进行操作。所以 Scala 并不推荐将属性设为 private,再为其设置
public 的 get 和 set 方法的做法。但由于很多 Java 框架都利用反射调用 getXXX 和 setXXX 方
法,有时候为了和这些框架兼容,也会为 Scala 的属性设置 getXXX 和 setXXX 方法(通过
@BeanProperty 注解实现)
二.访问权限
( 1) Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字。
( 2) private 为私有权限,只在类的内部和伴生对象中可用。
( 3) protected 为受保护权限, Scala 中受保护权限比 Java 中更严格,同类、子类可以
访问,同包无法访问。
( 4) private[包名]增加包访问权限,包名下的其他类也可以使用
对象
1.自动推导变量类型不能多态,所以多态需要显示声明(?)
2.构造器:Scala包括主构造器和辅助构造器。
注:辅助构造器不能直接构建对象,必须直接或间接调用主构造方法。
3.构造器里的三种参数设置
class Test(name:String,var age:Int,val sex:String) {
/*
* name:局部变量
* age:成员变量
* sex:只读成员变量
* */
var name1:String = name
}
继承和多态
1.scala中属性和方法都是动态绑定
class a{
val name:String = "a"
def hello(): Unit = {
println("hello a")
}
}
class aSon extends a{
override val name:String = "aSon"
override def hello(): Unit = println("hello b")
}
object Test{
def main(args: Array[String]): Unit = {
var aa = new aSon
println(aa.name)
aa.hello()
}
}
输出是:aSon ,hello b。如果是java,输出是a,hello b
抽象类
1.重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override
2.子类中调用父类的方法使用 super 关键字
3.子类对抽象属性进行实现,父类抽象属性可以用 var 修饰;子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var。
因为 var 修饰的为可变变量,子类继承之后就可以直接使用,没有必要重写(但是写var不会报错)
匿名子类
//Person是抽象类
val person = new Person {
override val name: String = "teacher"
override def hello(): Unit = println("hello teacher")
单例对象(伴生对象)
Scala语言是完全面向对象的语言, 所以并没有静态的操作( 即在Scala中没有静态的概
念) 。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象
来模拟类对象, 该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴
生对象,这个类的所有“静态” 内容都可以放置在它的伴生对象中声明。
说明
( 1)单例对象采用 object 关键字声明
( 2)单例对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。
( 3)单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问。
**apply方法**
( 1)通过伴生对象的 apply 方法, 实现不使用 new 方法创建对象。
( 2)如果想让主构造器变成私有的,可以在()之前加上 private。
( 3) apply 方法可以重载。
( 4) Scala 中 obj(arg)的语句实际是在调用该对象的 apply 方法,即 obj.apply(arg)。用
以统一面向对象编程和函数式编程的风格。
( 5)当使用 new 关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构
建对象时,调用的其实时伴生对象的 apply 方法。
特质(接口)
基础
1.所有的 Java 接口都可以当做 Scala 特质使用
2.动态混入:可灵活的扩展类的功能
val t2 = new Teacher with SexTrait {
override var sex: String = "男"
}
println(t2.sex)
特质叠加
第一种,一个类( Sub)混入的两个 trait( TraitA, TraitB)中具有相同的具体方法,且两个 trait 之间没有任何关系,解决这类冲突问题,直接在类( Sub)中重写冲突方法
第二种,一个类( Sub)混入的两个 trait( TraitA, TraitB)中具有相同的具体方法,且两个 trait 继承自相同的 trait( TraitC),及所谓的“钻石问题”,解决这类冲突问题, Scala采用了特质叠加的策略。
注:特质叠加顺序
特质自身类型
使用_:Name(with Name)=>或this:Name(with Name)=> 将Name类/接口/特质注入
class User(val name: String, val age: Int)
class Dao {
def insert(user: User) = {
println("insert into database :" + user.name)
}
}
trait APP {
_: Dao =>
def login(user: User): Unit = {
println("login :" + user.name)
insert(user)
}
}
object MyApp extends Dao with APP{
def main(args: Array[String]): Unit = {
login(new User("bobo", 11))
}
}
特质和抽象类的区别
1.优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
2.如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,
而特质不行( 有无参构造)
**类型检查和转换
( 1) obj.isInstanceOf[T]:判断 obj 是不是 T 类型。
( 2) obj.asInstanceOf[T]:将 obj 强转成 T 类型。
( 3) classOf 获取对象的类名。
val pClass: Class[Person] = classOf[Person]
枚举类和应用类
// 枚举类
object Color extends Enumeration {
val RED = Value(1, "red")
val YELLOW = Value(2, "yellow")
val BLUE = Value(3, "blue")
}
// 应用类
object test extends App {
//不用main方法就能执行
println(Color.RED)
}
type定义类型
就是给原有类型换个名
type S = String
var v:S = "aa"
//true
println(v.isInstanceOf[String])
var v1:String = "aa"
//true
println(v1.isInstanceOf[S])