scala物件導向
Scala物件導向程式設計
1.課程目標
- 掌握Scala中物件導向程式設計
- 掌握Scala模式匹配
- 掌握Scala泛型高階內容
- 熟悉Scala中多執行緒程式設計模型
2.物件導向
2.1 類
-
定義: class 類名{ 成員變數 val/var 名稱=值 成員方法 def 方法名稱(引數列表):返回值={ 方法體 } } 建立物件: val 物件名稱=new 類名() //() 可寫可不寫 ()沒有引數的時候可以省略 /** * Person * name 不可變 * age 可變 * skill 陣列 * 方法: * def addSkill * def scanSkill */ class Person { val name = "itcast" //不可變 不需要setter var age = 13 //可變 需要setter getter val skill = new ArrayBuffer[String]() // def addSkill def addSkill(subject: String): Unit = { skill += subject } def scanSkill(): Unit = { skill.foreach((x: String) => println(x)) } } object Scala_01_class { def main(args: Array[String]): Unit = { val person = new Person println(person.name) person.age=14 println(person.age) person.addSkill("scala") person.addSkill("spark") person.scanSkill() } }
2.2 setter getter
-
/** * Student類 * name 不可變 * age 可變 * * 注意: * 1.如果一個方法 只返回結果 在方法內部不進行任何業務邏輯處理的話,就可以省略方法名稱後邊的小括號“()” * 2.通過def 定義屬性 */ class Student { val name = "itcast" //不需要提供setter 和getter private var _age = 10 //可變變數定義格式 : _名稱 //setter def age_(age: Int) = this._age = age //getter def age=this._age } object Scala_02_class { def main(args: Array[String]): Unit = { val student = new Student student.age_(10) println(student.age) } }
2.3 方法的呼叫原則
-
/** * Teacher 類 * teach方法 * * 注意:teacher teach "spark" 這種呼叫方式只適用於一個引數的方法 */ class Teacher{ def teach(suject:String): Unit ={ println(s"教學:$suject") } } object Scala_03_class { def main(args: Array[String]): Unit = { val teacher = new Teacher teacher.teach("hadoop") teacher teach("scala") teacher teach "spark" 0 to 10 0 until 10 1 + 2 } }
2.4 Scala構造器
-
兩種構造器方式 主構造器 class 類名(引數*) 輔助構造器 定義在類當中 def this(引數*){ //第一行程式碼必須代用主構造 this(引數) } /** * 定義: Animal * 主構造器 (name) * 輔助構造(color,legs) */ class Animal(val name: String) { var _color = "red" var _legs = 2 //輔助構造(name,color,legs) def this(name: String, color: String, legs: Int) { this(name) //呼叫主構造器 this._color = color this._legs = legs } } object Scala_04_class { def main(args: Array[String]): Unit = { val a=new Animal("dog") val b=new Animal("cat","white",2) println(a.name) println(b._legs) } }
2.5 Scala中單例物件
-
建立方式: object 名稱{ 成員變數 成員方法 } 使用方式: 可以通過 名稱.成員變數/成員方法 形式使用。相當於java中static修飾變數和方法的呼叫 應用場景: 單例物件多應用於工具類或者工具物件 //建立工具物件 object CommonUtil { val PI = 3.14 def getDate = new Date } object Scala_05_object { def main(args: Array[String]): Unit = { println(CommonUtil.PI) println(CommonUtil.getDate) } }
2.6 伴生物件
-
當單例物件的名稱跟類名相同的時候,並且單例物件和類同時存在於同一個檔案中, 這裡這個物件就稱之為類的伴生物件。類是物件的伴生類 /** * SoftEngineer 類 * SoftEngineer object * 1.伴生類和伴生物件之間可以互相訪問 private屬性和方法 * 2.apply存於伴生物件中 能夠實現伴生類建立物件的功能 ,相當於java中的工廠模式的定義 */ class SoftEngineer(val exp:Int){ private var salary=1000 def getHasGF()={ SoftEngineer.hasGF //訪問伴生物件中私有變數 } val hasHair=SoftEngineer.hasHair() } object SoftEngineer{ private var hasGF=false //定義方法 訪問伴生類的私有變數 def getSalary()={ val engineer = new SoftEngineer(10) engineer.salary //訪問私有變數 } private def hasHair()={ true } def apply(exp:Int): SoftEngineer = new SoftEngineer(exp) } object Scala_06_object { def main(args: Array[String]): Unit = { val engineer = new SoftEngineer(10) println(engineer.getHasGF()) println(engineer.hasHair) println( SoftEngineer.getSalary()) val engineer2 = SoftEngineer(10) //Array(“dd”) List("ddd") } }
2.7 main函式
-
//通過繼承App的方式可以省略掉main //本質上 還是沒有省略 App中包含main函式 object Scala_07_object extends App { println("hello app") println(args(0)) }
2.8 繼承
-
格式:class 類名 extends 父類 1.scala單繼承 2.子類可以繼承父類的非私有的屬性和方法 3.子類可以重寫父類的方法和屬性 4.子類可以通過super關鍵詞呼叫父類的屬性和方法 /** * 父類 BigDataEngineer * 不可變 name * 可變 age * 方法 study * 子類 HadoopEngineer * */ class BigDataEngineer{ val name="BigData" var age=10 def study():Unit={ println("學習和開發") } } class HadoopEngineer extends BigDataEngineer{ //子類覆蓋父類中的study方法 override override def study(): Unit = { age=12 super.study() println("開發hadoop") } } object Scala_08_extends extends App{ val engineer = new HadoopEngineer println(engineer.name) engineer.study() } 問題:子類在建立物件的時候,是否呼叫了父類的構造器? scala中子類建立物件的時候也同樣呼叫了父類的構造器
-
Scala中構造機制
-
/** * 類 Person_09 * 子類 Sun_09 */ class Person_09{ println("Person_09") //主構造器呼叫完成之後直接呼叫 } class Sun_09 extends Person_09{ println("Sun_09") } object Scala_09_extends extends App { val sun_0 = new Sun_09 //根據列印結果 //在子類建立物件的過程中,呼叫了父類的構造器的 }
-
2.9 子類呼叫父類的構造器
-
子類主構造器沒有引數,父類主構造器有引數 子類主構造器有引數,父類主構造器也有引數 /** * 父類PC 電腦(cup memory) * 子類 NotePC * 桌上型電腦:DeskPC(cup memory) */ class PC(val cpu:Int,val memory:Int) class NotePC extends PC(cpu = 10,memory = 20) class DeskPC(cpu:Int,memory:Int) extends PC(cpu,memory) object Scala_10_extends { def main(args: Array[String]): Unit = { val n = new NotePC println(n.cpu) println(n.memory) println("----------------------") val deskPC=new DeskPC(30,60) println(deskPC.cpu) println(deskPC.memory) } }
2.10 抽象類
-
定義: abstract class 類名 1.可以定義抽象方法和抽象屬性(沒有初始化的屬性) 2.可以有非抽象的方法和非抽象屬性 3.如果方法或者屬性被final修飾,不能夠被重寫 /** * Employee 員工 * val name 抽象 * var age 非抽象的 * 抽象方法 work * 非抽象方法 study * final 方法:sleep */ abstract class Employee { val name: String //抽象屬性 資料型別不能夠省略 var age = 25 def work(): Unit //抽象方法返回值型別不能夠省略 def study(): Unit = { println("學習公司文化") } final def sleep(): Unit = { println("休息") } } class ScalaEmployee extends Employee { /** * override 如果覆蓋的是非抽象的方法或者屬性 這裡不能夠省略 * 如果覆蓋的是抽象方法或者屬性 這裡可以省略 */ override val name: String = "scala" override def work(): Unit = { println("開發scala應用程式") } } object Scala_11_extends extends App { private val employee = new ScalaEmployee println(employee.name) employee.work() employee.study() }
2.11匿名內部類
-
應用場景: ScalaProgramer 只會開發scala應用程式。python class ScalaProgrammer { def workerByScala(): Unit = { println("開發scala應用程式") } } class pyAndScaProgrammer extends ScalaProgrammer{ def workerByPython(): Unit = { println("學習並開發python") } } object Scala_12_innerclass { def main(args: Array[String]): Unit = { //python專案 臨時性需求 val scala= new ScalaProgrammer { def workerByPython(): Unit = { println("學習並開發python") } } scala.workerByPython() scala.workerByScala() println(scala.getClass) } }
2.12 超級父類
-
Any 超級分類 AnyRef 所有引用型別物件的超級父類 ScalaProgrammer AnyVal 所有值型別物件的超級父類 Int Double...
2.13 型別轉換和型別判斷
-
子類繼承父類,父類的引用可以指向子類物件。父類的引用是多型的。多型的問題 :型別轉換異常 * val worker = w.asInstanceOf[Worker] 1. 物件.isInstanceOf[型別] 模糊判斷 不精準 * 2. 物件.getClass=classOf[型別] class Worker { def work(): Unit = { println("工作") } } class JavaWorker extends Worker { def workByJava(): Unit = { println("開發java專案") } } object Scala_13_change { def boss(w: Any): Unit = { //將any物件轉換成 worker物件 //判斷物件的型別 /** * 1. 物件.isInstanceOf[型別] 模糊判斷 不精準 * 2. 物件.getClass=classOf[型別] */ if (w.isInstanceOf[Worker]) { val worker = w.asInstanceOf[Worker] worker.work() } else { println("回家等訊息") } } def boss2(w: Any): Unit = { //將any物件轉換成 worker物件 //判斷物件的型別 /** * 1. 物件.isInstanceOf[型別] 模糊判斷 不精準 * 2. 物件.getClass=classOf[型別] */ if (w.getClass()==classOf[JavaWorker]) { val worker = w.asInstanceOf[JavaWorker] worker.workByJava() } else { println("回家等訊息") } } def main(args: Array[String]): Unit = { val worker = new Worker /*boss(worker) boss(new Student)*/ val javaWorker = new JavaWorker boss2(worker) } }
2.14特質
-
特質的功能
- 格式:trait 名稱
- 功能:
- 特質可以作為java中的介面使用
- 特質可以作為抽象類使用
- 特質可以擴充套件物件的方法(1 個方法 --》多個方法)
- 特質可以擴充套件特定方法的功能
-
特質作為介面使用
-
/** * 定義 * trait 名稱 * 可以作為介面使用 * 1.可以定抽象方法 * 2.介面可以多實現 */ 格式:類 extends Tarit名稱 with Tarit名稱2 with Tarit名稱3 trait HelloTrait { def sayHellByChina(): Unit } trait HelloTraitHanguo { def sayHellByHanguo(): Unit } trait HelloTraitTaiguo { def sayHellByTaiguo(): Unit } class HelloTraitImpl extends HelloTrait with HelloTraitHanguo with HelloTraitTaiguo { override def sayHellByChina(): Unit = { println("你好") } override def sayHellByHanguo(): Unit = { println("阿尼哈沙有") } override def sayHellByTaiguo(): Unit = { println("薩瓦迪卡") } } object Scala_14_trait { def main(args: Array[String]): Unit = { val impl = new HelloTraitImpl impl.sayHellByChina() impl.sayHellByHanguo() impl.sayHellByTaiguo() } }
-
-
特質作為抽象類使用
-
trait AbstractTrait { //非抽象屬性和方法 val name = "itcast" def study(): Unit = { println("學習") } //抽象屬性和方法 val age: Int def work(): Unit } class AbstractTraitImpl extends AbstractTrait { override val age: Int = 10 override def work(): Unit = { println("工作") } } object Scala_15_trait extends App { private val impl = new AbstractTraitImpl println(impl.age) println(impl.name) impl.work() impl.study() } 特質和抽象類的區別 1.抽象類可以有自己的主構造器以及初始化引數 2.特質可以多實現但是抽象類只能進行單繼承或者多重繼承
-
-
特質擴充套件物件的功能
-
package cn.itcast.day02 class Tank { def shoot(): Unit = { println("發射子彈") } } trait Aim { def aim(): Unit = { println("瞄準") } } trait Scan { def scan(): Unit = { println("掃描") } } trait Fly{ def fly():Unit } object Scala_16_trait { def main(args: Array[String]): Unit = { val tank = new Tank with Aim with Scan with Fly{ override def fly(): Unit = { println("飛上天") } } tank.scan() tank.aim() tank.shoot() tank.fly() } }
-
-
特質擴充套件特定方法的功能
-
super: 線性呼叫的標誌符,線性是動態過程 是根據特質的混入順序有關的 線性執行順序:自右向左的過程 class Tank2 { def shoot(): Unit = { println("發射") } } trait Aim2 extends Tank2 { override def shoot(): Unit = { println("瞄準") super.shoot() } } trait Scan2 extends Tank2 { override def shoot(): Unit = { println("掃描") super.shoot() } } class SuperTank extends Tank2 with Aim2 with Scan2 object Scala_17_trait { def main(args: Array[String]): Unit = { val tank = new SuperTank tank.shoot() } }
-
-
特質構造機制
-
構造機制的執行原則: 從左往右 自上而下 trait T0{ println(0) } trait T1{ println(1) } trait T2{ println(2) } trait T3 extends T1{ println(3) } class Timpl extends T0 with T3 with T2 with T1{ println("Timpl") } object Scala_18_trait extends App { //1 2 1 3 0 // Timpl 1 2 1 3 0 new Timpl // 從左往右 自上而下 }
-
3. 模式匹配
-
功能類似於java中switch結構,但是要比swith強大的多
- 數值
- 資料型別
- Array
- List
- Tuple
- Map
- 自定義資料型別
-
結構: value match { case 需要匹配值或者型別 =>{ 執行邏輯} case _ => {執行邏輯} //預設的匹配 }
-
模式匹配值匹配
-
//值匹配 val arr = Array("hadoop", "scala", "spark") var value = arr((math.random * arr.size).toInt) //println("value:" + value) value="java" /** * value match { * case 需要匹配值或者型別 =>{ 執行邏輯} * case _ => {執行邏輯} //預設的匹配 * } */ value match { case "hadoop" => println("匹配Hadoop") case "scala" => println("匹配scala") case "spark" => println("匹配spark") case _ =>println("預設匹配") }
-
-
資料型別匹配
-
object DataType { def main(args: Array[String]): Unit = { val arr=Array("hadoop",1.34,10,true) var value = arr((math.random * arr.size).toInt) println("value:"+value) value match { case s:String => println(s+"-------------") case d:Double => println(d+"-------------") case i:Int => println(i+"-------------") case b:Boolean =>println(b+"-------------------") } } }
-
-
模式匹配陣列
-
object MatchArray{ def main(args: Array[String]): Unit = { val arr=Array("hadoop",1.34,10,true) arr match { //能否有個配所有array //非精確匹配 case Array("hadoop1",_*) =>println("333333") //佔位符匹配 case Array("hadoop",1.34,_,_) =>println("222222222") //精確匹配 case Array("hadoop",1.34,10,true) =>println("111111") case Array(_*) =>println("4444444") } } }
-
-
模式匹配列表
-
object MatchList{ def main(args: Array[String]): Unit = { val list=List("hadoop","spark","scala") list match { case "hadoop"::"spark"::"scala"::Nil =>println("sfsfsfdsfsdsdfd") //模糊匹配 case List(x,_*) =>println(x) case List(x,y,_) =>println(x+"\t"+y) //精確匹配 case List(x,y,z) =>println(x+"\t"+y+"\t"+z) case List("hadoop","spark","scala") => println("精確匹配list") } } }
-
-
模式匹配Tuple
-
object MatchTuple { def main(args: Array[String]): Unit = { val t = ("hadoop", 1.23, 10, true) t match { case (x,_,_,_) =>println("sdfdsfds") case _ =>println("預設匹配。。。。") //case ("hadoop",_*) =>println("") case ("hadoop",_,_,_) =>println("匹配佔位符tuple") case ("hadoop", 1.23, 10, true) =>println("精確匹配tuple") } } }
-
-
模式匹配Map
-
object MatchMap{ def main(args: Array[String]): Unit = { val map=Map("hadoop"->100,"scala"->50) val value=map.get("java") value match { case Some(x) =>println(x) case None =>println("沒有值") } } }
-
-
模式匹配自定資料型別
-
樣例類 case class 名稱
- 樣例類跟普通類區別:樣例類能夠自動構建apply方法
-
樣例物件
- case object 名稱 :應用場景 只是作為標誌
-
case class Task(name: String) case object TaskObject object MatchCaseClass { def main(args: Array[String]): Unit = { val arr = Array(Task("itcast"), TaskObject) val value = arr((math.random * arr.size).toInt) println("value:" + value) Task("lisi") match { case Task(name) => println("name:" + name) case TaskObject => println("匹配樣例物件") } } }
-
4. 偏函式 x=>y
-
把模式匹配這種形式 放在一個方法或者一個函式中,就構成一種新的函式,偏函式 //方法 def 名稱(引數)= value math{ case 操作 } //函式 val 名稱:PartialFunction[輸入資料型別,返回值資料型別] ={ case 操作 } object Scala_20_pianhanshu { def intMatch(x: Int) = x match { case 10 => println("10") case 100 => 100 } def main(args: Array[String]): Unit = { intMatch(10) println(intMatch(100)) val matchFuncion: PartialFunction[Int, String] = { case x:Int => x + " is even" } println(matchFuncion(10)) } }
5.逆變協變非變
-
class Apple class RedApple extends Apple class Box[T] 問題:RedApple 是 Apple 子類, Box[RedApple] 是不是 Box[Apple]子類? 假如 Box[RedApple] 是 Box[Apple]子類 val box:Box[Apple] =new Box[RedApple] 則成立 ,反之則不成立 答案 :以上假設不成立 要想讓以上操作成立 需要協變操作 RedApple extends Apple class Box[T] a=Box[Apple] b=Box[RedApple] class Box[+T] a=Box[Apple] b=Box[RedApple] class Box[-T] a=Box[Apple] b=Box[RedApple] 逆變:class Box[-T] val box:Box[RedApple] =new Box[Apple] class RedApple extends Apple class Box[+T] //協變 class Box2[-T] object Scala_21_fanxin { def main(args: Array[String]): Unit = { val box: Box[Apple] = new Box[RedApple] val box2:Box2[RedApple] =new Box2[Apple] } } Son extends Person 總結:a=ArrayList<Person> b=ArrayList<Son> C[T]: A是B的子類 C[A]與C[B]之間沒有任何關係 非變操作 C[+T]: A是B的子類 C[A]是C[B]的子類 協變操作 C[-T]: A是B的子類 C[A]是C[B]的父類 逆變操作
6.上下界
-
上下界 影響的是方法的入參 U>:Class U 帶表的class本身以及其父類 下界操作 下界限制不住 U<:Class U 代表class 本身以及其子類 上界操作 class OldMan extends Man class OldOldMan extends OldMan class YoungMan extends Man class ChildMan extends YoungMan class Sport { //新增下界操作 U 代表的是 OldMan 本身 或者是其父類 下界操作 其實是無下界 def guangchangwu[U >: OldMan](man: U): Unit = { println("廣場舞") } //U 帶表示 YoungMan本身以及其子類 def qiaodaima[U<:YoungMan](man: U): Unit = { println("敲程式碼") } } object Scala_22_upanddown { def main(args: Array[String]): Unit = { val sport = new Sport val yman = new YoungMan val oman = new OldMan val ooman=new OldOldMan val cman = new ChildMan /* sport.guangchangwu(yman) sport.guangchangwu(oman) sport.guangchangwu(ooman)*/ sport.qiaodaima(cman) } }
7.Scala併發操作
-
格式: class 執行緒類 extends Actor{ def act() } //啟動執行緒 actor.start() /** * 建立執行緒類 MyActor */ class MyActor(val name: String) extends Actor { override def act(): Unit = { for (i <- 0 to 10) { println(name + ":" + i) } } } object Scala_23_actor { def main(args: Array[String]): Unit = { val itcast = new MyActor("itcast") val tian = new MyActor("Tian") itcast.start() tian.start() } }
-
Actor基於訊息機制的併發
-
actor能夠傳送訊息 和接受訊息,根據訊息的不同,去執行不同的業務邏輯
-
! 傳送訊息
-
class MyActor2 extends Actor { override def act(): Unit = { var flag = true while (flag) receive { //阻塞 case "start" => println("啟動成功") //執行邏輯完成後自動退出 case "test" => println("測試") case "end" => { println("退出") flag = false } } } } object Scala_24_actor { def main(args: Array[String]): Unit = { val actor = new MyActor2() actor.start() actor ! "start" actor!"test" actor ! "end" } }
-
-
loop react
-
class MyActor2 extends Actor { override def act(): Unit = { loop{ react{ case "start"=>println("啟動成功過") case "test" =>println("測試") case "end"=> exit() } } } } object Scala_24_actor { def main(args: Array[String]): Unit = { val actor = new MyActor2() actor.start() actor ! "start" actor!"test" actor ! "end" } }
-
-
Actor傳送訊息的三種方式
-
! 非同步訊息 並且無返回值
-
!? 同步訊息 有返回值
-
!! 非同步訊息 有返回值 Future[Any]
-
同步訊息和非同步訊息
- 同步訊息:傳送訊息後,會等待訊息執行邏輯完成,再返回
- 非同步訊息:傳送訊息後直接返回,返回會在將來的某一時刻返回 Future[Any]
-
總和案例:
- 結合樣例類方式 來整同步訊息和非同步訊息以及返回值
- 需要構建3個樣例類
-
/** * 訊息模型 * 同步訊息 * 非同步訊息 * 返回值訊息 */ case class SynMsg(msg: String, time: Long) case class AsynMsg(msg: String, time: Long) case class ReplayMsg(msg: String) class MsgActor extends Actor { override def act(): Unit = { loop { react { case SynMsg(msg, time) => { Thread.sleep(time) println(msg) sender ! ReplayMsg(msg + "---SynMsg-----") } case AsynMsg(msg, time) => { Thread.sleep(time) println(msg) sender ! ReplayMsg(msg + "---AsynMsg-----") } } } } } object Scala_25_actor { def main(args: Array[String]): Unit = { val actor = new MsgActor actor.start() /*val msg1=actor!?SynMsg("itcast",5000) val msg2=actor!?SynMsg("itcast2",1000) println(msg1) println(msg2)*/ val msg1 = actor !! AsynMsg("itcast", 5000) val msg2 = actor !! AsynMsg("itcast2", 1000) val list = ListBuffer[Future[Any]]() list += msg1 list += msg2 while (list.size > 0) { for (msg <- list) { //msg:Future[Any] //判斷future是否接收到資料 if (msg.isSet) { //ture 代表已經接受到資料 val replayMsg = msg.apply().asInstanceOf[ReplayMsg] println(replayMsg.msg) list -= msg } } } } }
-
-
基於Actor的wordcount案例
-
操作步驟:
- 準備檔案 a.txt b.txt c.txt
- 構建actor
- 通過樣例類 構建訊息的載體 case FilePathMsg(path:String)
- actor接受訊息 並且處理檔案資料
- 接受返回值 並且將返回值放在ListBuffer進行管理
- 對ListBuffer進行迴圈操作,拿到檔案處理資料,把檔案處理資料放在一個集合中
- 對集合進行彙總處理
-
package cn.itcast.day02 import java.io.File import scala.actors.{Actor, Future} import scala.collection.mutable.{ArrayBuffer, ListBuffer} import scala.io.Source /** * 樣例類方式構建訊息載體 */ case class FilePathMsg(path: String) //返回值訊息 case class FileResultMsg(result: Map[String, Int]) class FileActor extends Actor { override def act(): Unit = { loop { react { case FilePathMsg(path) => { //讀取檔案資料 並且進行處理 Map val map: Map[String, Int] = Source.fromFile(new File(path)).getLines().mkString(",").split(",") .map((x: String) => (x, 1)).groupBy((t: Tuple2[String, Int]) => t._1) .mapValues((arr: Array[Tuple2[String, Int]]) => arr.length) sender ! FileResultMsg(map) } } } } } object Scala_26_wordcount { def main(args: Array[String]): Unit = { val arr = Array("d:/a.txt", "d:/b.txt", "d:/c.txt") val list = ListBuffer[Future[Any]]() //陣列封裝了每個檔案處理好的資料 val fileDataArray = ArrayBuffer[Map[String, Int]]() for (path <- arr) { val actor = new FileActor actor.start() //傳送非同步訊息 並且接受到每個檔案的處理結果 val result = actor !! FilePathMsg(path) list += result } while (list.size > 0) { for (f <- list if f.isSet) { val fileResult = f.apply().asInstanceOf[FileResultMsg] fileDataArray += fileResult.result list -= f } } val wordcount = fileDataArray.flatten.groupBy((t: Tuple2[String, Int]) => t._1) .mapValues((arr: ArrayBuffer[Tuple2[String, Int]]) => { arr.map((t: Tuple2[String, Int]) => t._2).sum }) println(wordcount) } }
-
相關文章
- Scala學習 2 Scala物件導向物件
- Scala的物件導向程式設計物件程式設計
- 從 Java 到 Scala(一):物件導向談起Java物件
- Cris 的 Scala 筆記整理(七):物件導向筆記物件
- 物件導向-物件導向思想物件
- Cris 的 Scala 筆記整理(九):物件導向高階筆記物件
- 程式導向與物件導向物件
- 物件導向與程式導向物件
- “程序導向”和“物件導向”物件
- Cris 的 Scala 筆記整理(八):物件導向中級-封裝筆記物件封裝
- 物件導向物件
- 物件導向,搞定物件物件
- PHP 物件導向 (九)物件導向三大特徵PHP物件特徵
- JAVA物件導向基礎--物件導向介紹Java物件
- 從程式導向到物件導向物件
- 物件導向(下)物件
- 物件導向 -- 反射物件反射
- PHP物件導向PHP物件
- Java — 物件導向Java物件
- JavaScript 物件導向JavaScript物件
- JS物件導向JS物件
- 物件導向(上)物件
- 物件導向--下物件
- 物件導向(oop)物件OOP
- 物件導向trick物件
- 物件導向-介面物件
- 物件導向One物件
- 物件導向思想物件
- Java物件導向Java物件
- [Java物件導向]Java物件
- 談談“物件導向”與“程式導向”物件
- 從物件導向到模式再到真正的物件導向 (轉)物件模式
- iOS 開發之 OOA (物件導向分析) & OOD (物件導向設計)& OOP (物件導向程式設計)iOS物件OOP程式設計
- python-程式導向、物件導向、類Python物件
- php中的程式導向與物件導向PHP物件
- Js物件導向(1): 理解物件JS物件
- Java物件導向——類與物件Java物件
- Cris 的 Scala 筆記整理(八):物件導向中級-繼承和多型筆記物件繼承多型