1寒波、類
1乘盼、類的定義和訪問限制符
/**
* 類的定義,變量聲明與訪問限制
* 在Scala中俄烁,類并不用聲明為public蹦肴。
*Scala源文件中可以包含多個(gè)類,所有這些類都具有公有可見性猴娩。
* Created by 12706 on 2017/11/27.
*/
//private[scu]:包可見性scu是包名阴幌,除了該包和子包其他包不可見
//Person private表示構(gòu)造器(無參的主構(gòu)造器)私有化了,除了伴生對象外其他對象里面一旦創(chuàng)建運(yùn)行會(huì)出錯(cuò)
private[scu] class Person private {
//val修飾的屬性,外部只能訪問該屬性而不能修改(反編譯后能看到只有g(shù)et方法而沒有set方法)
val id = 110
//var 修飾的屬性卷中,既有g(shù)et方法也有set方法
var name = "小明"
//private修飾的屬性(類私有字段)只能在當(dāng)前類(以及伴生對象 object Person)中訪問
private val age : Int = 18
//對象私有字段,訪問權(quán)限更加嚴(yán)格的矛双,連伴生對象都不能訪問,只能當(dāng)前類才行
private[this] val height : Int = 16
//getHeight()當(dāng)然也行
private def getHeight = {
height
}
}
//伴生對象,類和伴生對象之間可以相互訪問私有的方法和屬性
object Person {
def main(args: Array[String]): Unit = {
//創(chuàng)建對象,當(dāng)然用new Person()也行
val p = new Person
//訪問對象屬性,訪問不到height屬性
println("id:" + p.id)
println("姓名:" + p.name)
println("年齡:" + p.age)
//通過方法獲height屬性
val height = p.getHeight;
println("身高:" + height)
//修改屬性,只能修改到name
p.name = "小雨"
println("姓名:" + p.name)
}
}
class Man {}
object Man {
def main(args: Array[String]): Unit = {
// 運(yùn)行會(huì)出錯(cuò)蟆豫,因?yàn)闃?gòu)造器被私有化了
// val p = new Person
}
}
對上面的demo進(jìn)行反編譯议忽,java代碼一目了然
public class Person
{
private final int id = 110;
private String name = "小明";
private final int main$java$cn$scu$scala$day02$Person$$age = 18;
private final int height = 16;
public static void main(String[] paramArrayOfString)
{
Person..MODULE$.main(paramArrayOfString);
}
public int id()
{
return this.id;
}
public String name() { return this.name; }
public void name_$eq(String x$1) { this.name = x$1; }
public int main$java$cn$scu$scala$day02$Person$$age() {
return this.main$java$cn$scu$scala$day02$Person$$age;
}
public int main$java$cn$scu$scala$day02$Person$$getHeight()
{
return this.height;
}
}
2、構(gòu)造器
/**
* 每個(gè)類都有主構(gòu)造器十减,主構(gòu)造器的參數(shù)直接放置類名后面栈幸,與類交織在一起
* Created by 12706 on 2017/11/27.
*/
//height : Int 相當(dāng)于private[this] height : int
//反編譯的時(shí)候能看到成員變量有id,name,age
class People(val id : Int, var name : String, height : Int, private var age : Int = 18) {
}
object People {
def main(args: Array[String]): Unit = {
//age有初始值所以創(chuàng)建對象時(shí)可以不指定
val p = new People(1,"小明",60);
//訪問不了height屬性愤估,height為對象私有字段
println(p.id + " " +p.age + " " +p.name)
val p2 = new People(1,"小明",60,28);
println(p2.id + " " +p2.age + " " +p2.name)
}
}
輸出
1 18 小明
1 28 小明
/**
* 輔助構(gòu)造器的定義
* Created by 12706 on 2017/11/27.
*/
class Student(val id : Int, val name : String) {
println("執(zhí)行主構(gòu)造器!")
//用this關(guān)鍵字定義輔助構(gòu)造器
def this(id : Int, name : String, age : Int){
//每個(gè)輔助構(gòu)造器必須以主構(gòu)造器或其他的輔助構(gòu)造器的調(diào)用開始
this(id,name)
println("執(zhí)行輔助構(gòu)造器")
}
}
object Student {
def main(args: Array[String]): Unit = {
val stu = new Student(1,"小明",20)
//同樣還是訪問不到age的
println(stu.name)
}
}
/**
* 主構(gòu)造器會(huì)執(zhí)行類定義中的所有語句
* Created by 12706 on 2017/11/27.
*/
class Prop {
println("執(zhí)行主構(gòu)造器")
//定義方法
def method(): Unit ={
println("用我來讀取文件內(nèi)容 !")
}
//讀取外部文件內(nèi)容
try {
//讀取的整個(gè)文件后轉(zhuǎn)為String
val context = Source.fromFile("d://words.txt").mkString
println(context)
}catch {
case e :Exception => e.printStackTrace()
}finally {
println("讀取文件完畢")
}
}
object Prop {
def main(args: Array[String]): Unit = {
val prop = new Prop
println("================")
prop.method
}
}
輸出
執(zhí)行主構(gòu)造器
hello tom
hello jerry
hello tom
hello jerry
hello tom
hello tom
讀取文件完畢
================
用我來讀取文件內(nèi)容 !
2速址、對象
1、單例對象
在Scala中沒有靜態(tài)方法和靜態(tài)字段昔园,但是可以使用object這個(gè)語法結(jié)構(gòu)來達(dá)到同樣的目的
1.存放工具方法和常量
2.高效共享單個(gè)不可變的實(shí)例
3.單例模式
/**
* java中SessionFactory(hibernate或者是mybatis(SqlSessionFactory))的設(shè)計(jì)就是
* 單例的默刚,通過它來獲取Session對象荤西。使用scala來進(jìn)行簡單模擬
* Created by 12706 on 2017/11/27.
*/
//下面相當(dāng)于java的靜態(tài)塊
object SessionFactory{
var counts = 5;
val buffer = new ArrayBuffer[Session](5)
while (counts>0) {
//給buffer緩存塞入5個(gè)Sessio對象
val session = new Session
buffer += session
counts -= 1
}
//獲取session對象,相當(dāng)于java的靜態(tài)方法
def getSession(): Unit ={
//緩存中取session
buffer.remove(0)
}
def main(args: Array[String]): Unit = {
//單例對象邪锌,不需要new养篓,用【類名.方法】調(diào)用對象中的方法
val session = SessionFactory.getSession
println(session)
}
}
class Session {
}
2柳弄、伴生對象
在Scala的類中碧注,與類名相同的對象叫做伴生對象,類和伴生對象之間可以相互訪問私有的方法和屬性
/**
* 伴生對象與類之間私有屬性的訪問
* Created by 12706 on 2017/11/27.
*/
class Dog {
private val name : String = "旺財(cái)"
def bark(){
//訪問伴生對象的私有屬性
println(Dog.voice)
}
}
object Dog {
private val voice : String = "wangwang"
def main(args: Array[String]): Unit = {
val dog = new Dog
//訪問對象的私有name屬性
println(dog.name)
dog.bark()
}
}
2轩端、apply方法
/**
* apply方法:通常我們會(huì)在類的伴生對象中定義apply方法基茵,
* 當(dāng)遇到類名(參數(shù)1,...參數(shù)n)時(shí)apply方法會(huì)被調(diào)用
* Created by 12706 on 2017/11/27.
*/
class Point {
private var x : Int = 2
println("主構(gòu)造器被調(diào)用")
def this(x : Int){
this()
this.x = x
}
}
object Point {
def apply(): Unit ={
println("apply()方法被調(diào)用")
}
def apply(x : Int, y : Int): Unit = {
println("apply(x : Int, y : Int)方法被調(diào)用")
}
def apply(x : Int): Point = {
println("apply(x : Int)方法被調(diào)用")
new Point(x)
}
def main(args: Array[String]): Unit = {
val p1 = new Point
println("===================")
//注意兩者區(qū)別,調(diào)用apply方法的時(shí)候不會(huì)執(zhí)行主構(gòu)造器方法
val p2 = Point()
val p3 = Point(3,4)
println("===================")
val p4 = Point(3)
println(p4.x)
}
}
輸出
主構(gòu)造器被調(diào)用
===================
apply()方法被調(diào)用
apply(x : Int, y : Int)方法被調(diào)用
===================
apply(x : Int)方法被調(diào)用
主構(gòu)造器被調(diào)用
3
4、應(yīng)用程序?qū)ο?br> Scala程序都必須從一個(gè)對象的main方法開始根灯,可以通過擴(kuò)展App特質(zhì),不寫main方法纳猪。
/**
* 應(yīng)用程序?qū)ο笫系蹋瑔卫龑ο螅ɑ蛘甙樯鷮ο螅├^承App即可丽猬,App中定義了main方法被繼承過來了
* 所以AppDemo中不需要寫main方法了
* Created by 12706 on 2017/11/27.
*/
object AppDemo extends App{
val arr = Array(1,2,3,4)
println(arr.toBuffer)
}
3、繼承
1谬以、拓展類
在Scala中擴(kuò)展類的方式和Java一樣都是使用extends關(guān)鍵字为黎,但是并沒有使用implements來實(shí)現(xiàn)接口铭乾,都是用extends炕檩。如果繼承一個(gè)類的同時(shí)也實(shí)現(xiàn)了很多接口,那么用extends 父類 with 接口1 with 接口2 with…
2泉沾、方法的重寫
方法重寫就是子類中對父類的方法實(shí)現(xiàn)重寫跷究。
java中接口中都是抽象方法俊马,但是scala中可以有實(shí)現(xiàn)肩杈,而且關(guān)鍵字是trait稱為特質(zhì)锋恬。但是重寫一個(gè)非抽象方法必須使用override關(guān)鍵字。
3彤悔、類型檢查和轉(zhuǎn)換
obj.isInstanceOf[C](scala中) ,obj instanceof C(java中)晕窑。obj是不是C類型
obj.asInstanceOf[C](scala中)杨赤,(C)obj(java中)疾牲,obj類型強(qiáng)轉(zhuǎn)為C類型。
classOf[C](scala中)焰枢,C.class济锄。獲取C類型
/**
* Men是Human類(繼承類)荐绝,同時(shí)擁有動(dòng)物的行為(實(shí)現(xiàn)接口)
* Created by 12706 on 2017/11/27.
*/
//Human是類必須接在extends后面
class Men extends Human with Animall{
def say(): Unit = {
println("大家好,我的名字叫:" + name)
}
//重寫父類已經(jīng)實(shí)現(xiàn)的方法需要加override關(guān)鍵字低滩,父類沒實(shí)現(xiàn)那么可加可不加
override def getName(): String = {
this.name
}
}
object Men {
def main(args: Array[String]): Unit = {
val man = new Men
man.name = "xiaoming"
man.say()
println(man.getName())
//類型檢查
val b = man.isInstanceOf[Animall]
println(b)
}
}
abstract class Human {
var name : String = _
def say()
}
trait Animall {
def getName(): String = {
"monkey"
}
}
輸出
大家好,我的名字叫:xiaoming
xiaoming
true
_ 對變量進(jìn)行默認(rèn)初始化委造,比如var i:Int=_