(1)类的成员
class Student { //使用var定义一个可变的成员变量 var age=18 //使用val定义一不可变的成员变量 val name="zy" //定义一个私有化成员变量(伴生对象仍然可以访问) private var id=1001 //定义一个私有化成员变量(伴生对象也不可以访问) private[this] val address="anhui" //定义一个成员方法 def running(): Unit ={ println(this.name+"跑~") } }
注意点:
? - 在scala中声明类不要指定public,scala的文件名可以与类名不同。
? - 成员属性是否可以修改,取决于是否使用val修饰
? - 成员方法和属性能不能被访问,取决于修饰符,public(默认),private
(2)类的构造器
//在类上声明的是主构造器 class Student(val name:String,val age:Int) { //使用this为方法名,这个是辅助构造器 def this(name:String,age:Int){ this(name,age) } }
主构造器的注意点:
? - 在类上定义的构造器称为主构造器
? - 主构造器包含了整个所有的类的代码块,所以,默认的定义的类中的所有能执行的代码都会执行
? - 主构造器中的参数如果没有使用任何修饰符,默认的就是 private[this] val
? - 主构造器中的参数如果使用val或者var修饰,就相当于一个普通的成员变量
辅助构造器的注意点:
? - 当主构造器被class private Student()修饰了,可以使用辅助构造器创建该类对象
? - 辅助构造器必须使用def修饰,并且方法名为this
? - 辅助构造器中的参数不能使用var或者val 修饰
? - 辅助构造器中的第一行代码必须是:调用其他的构造器
(3)类的私有化
//使用private修饰主构造器,表示私有化类 class Student private(val name: String,val age: Int) { def this(name: String,age: Int) { this(name,age) } } //使用 private[this]私有化类 class Person private[this](val name: String,val age: Int) { }
注意点:
? - 被private修饰的类,被私有化,不能其他类不能创建该类实例,但是伴生对象可以
? - 如果想让伴生对象都不能创建该类的实例,可以使用:class private[this]
? - 当主构造器被class private Student()修饰了,可以使用辅助构造器创建该类对象
??
2.伴生对象
?在scala的类中,与类名相同的单例对象叫做伴生对象。
? 特点:(假设现在有一个类:class Student,和一个伴生对象:object Student)
? ? - class Student是object Student的伴生类
? ? - object Student是class Student的伴生对象
? ? - 类和伴生对象之间可以相互访问私有的方法和属性
? ? - 伴生类和伴生对象的名称相同
例:
//使用private修饰主构造器,表示私有化类 class Student private { private val name="zs" private val age=18 } object Student{ //在伴生对象中创建私有化类的对象 val student=new Student() //在伴生对象中访问私有化的属性 val name=student.name val age=student.age }
单例对象:
单例对象表示,被object修饰,但是没有自己的伴生类。
例:
object person{ val name="zs" val age=18 }
特点:
? - scala 语言并不支持静态成员,没有静态方法和静态字段,Scala 通过单例对象 object 来解决
? - 单例对象中的所有成员和方法都是static的
? - 单例对象它本身就是一个单例,(因为不需要去 new)
apply方法
? 在讲集合和数组的时候,可以通过 val intList=List(1,2,3)这种方式创建初始化一个列表对象, 其实它相当于调用 val intList=List.apply(1,3),只不过 val intList=List(1,3)这种创建方式更简洁一点,但我们必须明确的是这种创建方式仍然避免不了 new,它后面的实现机制仍然是 new 的方式,只不过我们自己在使用的时候可以省去 new 的操作。通常我们会在类的伴生对象中定义 apply 方法,当遇到【类名(参数 1,...参数 n)】时 apply 方法会被调用。
? Apply也叫构建函数:把一堆零散的值构建成一个对象返回。
例:
object Test01 { def main(args: Array[String]): Unit = { //以下两种方式创建对象等效 val list01 = List(1,3) val list02 = List.apply(1,3) } }
特点:
? - apply方法只能定义在object中。
? - apply方法可以重载, 还是被系统自动调用的
?
3.scala的抽象类
? 定义:抽象类是一种不能被实例化的类,抽象类中包括了若干不能完整定义的方法,这些方法由子 类去扩展定义自己的实现。
? 特点:
? ? - 如果在父类中,有某些方法无法立即实现,而需要依赖不同的子类来覆盖,重写实现自 己不同的方法实现。此时可以将父类中的这些方法不给出具体的实现,只有方法签名,这 种方法就是抽象方法。
? ? - 一个类中如果有一个抽象方法,那么类就必须用 abstract 来声明为抽象类,此时抽象 类是不可以实例化的
? ? - 在子类中覆盖抽象类的抽象方法时,不需要使用 override 关键字
例:
abstract class Annimal { def runing() def eat() } class Cat extends Annimal { def runing(): Unit = { println("running~") } def eat(): Unit = { println("eatting~") } }
?
4.scala的继承
例:
//父类 class Annimal { //被final修饰的无法被继承 final private val name = "Annimal" def runing(): Unit = { println("running~") } def eat(): Unit = { println("eatting~") } } //子类 class Cat extends Annimal { //重写父类的方法 override def runing(): Unit = { //调用父类原有的方法 super.runing() } }
注意:
? - 在 Scala 中扩展类的方式 和 Java 一样都是使用 extends 关键字
? - 继承就代表,子类可以从父类继承父类的 field 和 method;然后子类可以在自己内部放 入父类所没有,子类特有的 field 和 method;使用继承可以有效复用代码
? - 子类可以覆盖父类的 field 和 method;但是如果父类用 final 修饰,field 和 method 用 final 修饰,则该类是无法被继承的,field 和 method 是无法被覆盖的
? - 如果子类要重写一个父类中的非抽象方法,则必须使用 override 关键字
? - 使用 super 关键字,显式地指定要调用父类的方法/属性
?
5.scala的类型检查和转换
例:
object Test01 { def main(args: Array[String]): Unit = { val parent=new Annimal //父类 val chrild=new Cat //子类 //类型判断 println(chrild.isinstanceOf[Annimal]) //true //类型获取 println(classOf[Cat]) //class Cat //类型转换 val annimal: Annimal = chrild.asInstanceOf[Annimal] } } //父类 class Annimal { //被final修饰的无法被继承 final private val name = "Annimal" def runing(): Unit = { println("running~") } def eat(): Unit = { println("eatting~") } } //子类 class Cat extends Annimal { //重写父类的方法 override def runing(): Unit = { //调用父类原有的方法 super.runing() } }
?
6.scala的特质 (Trait)
(1)特质的介绍
? Scala 和 Java 语言一样,采用了很强的限制策略,避免了多继承的问题。在 Java 语言中,只允许继承一个超类,该类可以实现多个接口,但 Java 接口有其自身的局限性:接口中只能包括抽象方法,不能包含字段、具体方法。Scala 语言利用 trait 解决了该问题,在 Scala 的 trait 中,它不但可以包括抽象方法还可以包含字段和具体方法。特质在底层实现是采用的Java的抽象类。
例:
trait Annimal { val name = "Annimal" def runing(): Unit = { println("running~") } def eat() }
(1)特质的基本使用
特质的特点:
? - 特质里面的方法既可以实现,也可以不实现
? - 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
? - 特质不能设置带参数的构造:trait t(i: Int) {},参数 i 是非法的
? - 如果继承多个特质,使用第一个特质使用 extends,后面的使用 with
例:
trait Car { } trait Person{ } class transformers extends Car with Person{ }
(2)特质作为接口使用
? 将特质中的方法全部定义成为抽象方法。类可以使用extends的方式继承特质。scala 不支持对类进行多继承,但是支持多重继承 trait,使用 with 关键字即可。类继承 trait 后,必须实现其中的抽象方法,实现时不需要使用 override 关键字。
例:
trait MysqLDAO{ val id:Int def add(o:Any):Boolean def update(o:Any):Int def query(id:String):List[Any] } //如果有多个 trait 的话,则使用 with 关键字即可 class DaoImpl extends MysqLDAO with Serializable{ // 给父类中的抽象字段赋值。 override val id = 12 // 实现抽象方法 def add(o:Any):Boolean = true def update(o:Any):Int = 1 def query(id:String):List[Any] = List(1,3) }
(3)为实例对象混入 Trait
? 有时我们可以在创建类的对象时,指定该对象混入某个 Trait,这样,就只有这个对象混入该 Trait 的方法,而类的其他对象则没有。
例:
object Test01 { def main(args: Array[String]): Unit = { //会某一个对象混入特质 var HTQ_DHF =new Person() with DHF } } trait transformers trait HTQ extends transformers trait DHF extends transformers trait Person extends HTQ
(4)Trait 调用链
? scala 中支持让类继承多个 Trait 后,依次调用多个 Trait 中的同一个方法,只要让多个 Trait 的同一个方法中,在最后都执行 super.方法 即可。类中调用多个 Trait 中都有的这个方法时,首先会从最右边的 Trait 的方法开始执行,然后依 次往左执行,形成一个调用链条这种特性非常强大,其实就相当于设计模式中的责任链模式的一种具体实现依赖。
例:
object Test01 { def main(args: Array[String]): Unit = { val p=new Person_TraitChain("zhangxiaolong") p.sayHello } } trait Handler { //父类的trait 必须有实现体,不然会报错 def handler(data:String): Unit ={ println("Handler :"+data) } } trait Handler_A extends Handler{ override def handler(data:String): Unit = { println("Handler_A :"+data) super.handler(data) } } trait Handler_B extends Handler{ override def handler(data:String): Unit = { println("Handler_B :"+data) super.handler(data) } } trait Handler_C extends Handler{ override def handler(data:String): Unit = { println("Handler_C :"+data) super.handler(data) } } class Person_TraitChain(val name:String) extends Handler_C with Handler_B with Handler_A{ def sayHello={ println("Hello "+name) handler(name) } }
结果会打印:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。