大數據筆記(二十四)——Scala面向對象編程實例
===================== Scala語言的面向對象編程 ========================
一、面向對象的基本概念:把數據和操作數據的方法放到一起,作為一個整體(類 class)
面向對象的特征:
(1)封裝
(2)繼承
(3)多態
二、定義類: class,沒有類的修飾符: public、protected、private
class Student1 { //定義屬性 private var stuName:String = "Tom" private var stuAge:Int = 20 //定義方法(函數) def getStuName():String = stuName def setStuName(newName:String)= this.stuName = newName def getStuAge():Int = stuAge def setStuAge(newAge:Int) = this.stuAge = newAge } //開發一個測試程序,創建學生對象 // Java: public static void main()****** //概念:objec對象可以跟類名不一樣,如果一樣,這個object對象就是該類的伴生對象 object Student1{ //都是靜態 def main(args: Array[String]): Unit = { //創建學生對象 var s1 = newStudent1 //第一次輸出 println(s1.getStuName()+"\t" + s1.getStuAge()) //調用set方法 s1.setStuName("Mary") s1.setStuAge(25) //第二次輸出 println(s1.getStuName()+"\t" + s1.getStuAge()) //第三次輸出: 直接訪問類的私有成員 //問題:為什麽可以直接訪問類的私有成員??? ----> 討論:屬性的set和get方法 println(s1.stuName + "\t" + s1.stuAge) } }
運行:
三、屬性的get和set方法
/* 屬性的get和set方法 1、當定義屬性的時候,如果是private,Scala會自動生成對應的set和get方法 private var stuName:String = "Tom" (1) get方法:stuName (2) set方法: stuName_ 2、如何只有get方法,沒有set方法? ---> 將屬性定義為: 常量 val private val money:Int = 1000 3、不希望生成get和set方法: private[this] 該屬性只屬於該對象私有 */ class Student2 { //定義屬性 private var stuName:String = "Tom" //只有get方法 private val money:Int = 1000 } object Student2{ def main(args: Array[String]): Unit = { var s2 = new Student2 println(s2.stuName) //修改money值 ===> error 錯誤 //s2.money = 2000 } }
四、嵌套類(內部類): 類:Student 包含:課程Course
import scala.collection.mutable.ArrayBuffer class Student3 { //定義一個內部類(嵌套類): 學生選修的課程 //通過主構造器 class Course(val courseName:String,val credit:Int){ //其他的方法 } //屬性 private var stuName:String = "Tom" private var stuAge:Int = 20 //定義一個數組來保存該學生選修的課程 private var courseList = new ArrayBuffer[Course]() //定義方法:往學生信息中添加新的課程 def addNewCourse(cname:String,credit:Int): Unit ={ //創建一門課程 var c = new Course(cname,credit) //加入list courseList += c } } object Student3{ def main(args: Array[String]): Unit = { //創建學生 var s3 = new Student3 //給學生添加課程 s3.addNewCourse("Chinese",3) s3.addNewCourse("English",3) s3.addNewCourse("Math",3) //輸出 println(s3.stuName+"\t"+s3.stuAge) for(s <- s3.courseList) println(s.courseName + "\t" + s.credit) } }
運行:
五、構造器:(1)主構造器 (2)輔助構造器
package main.scala /** * Created by YOGA on 2018/2/3. * (1)主構造器:和類的申明在一起,只能有一個主構造器 * (2)輔助構造器:多個,通過關鍵字this */ class Student4(val stuName:String,val stuAge:Int) { //定義一個輔助構造器 def this(age:Int){ //調用主構造器 this("No Name",age) } } object Student4{ def main(args: Array[String]) { //使用主構造器創建學生對象 val s4 = new Student4("Tom",24) println(s4.stuName+ "\t" + s4.stuAge) //使用輔助構造器創建學生對象 var s5 = new Student4(25) println(s5.stuName+"\t"+s5.stuAge) } }
運行:
六、Object對象:相當於static關鍵字
1、單例模式:一個類只有一個對象
舉例:生成信用卡的卡號
package main.scala /** * Created by YOGA on 2018/2/3. */ object CreditCard { //變量:保存信用卡的卡號 //該屬性只屬於該對象 private[this] var creditCardNumber:Long = 0 //產生卡號 def generateNewCCNumber() = { creditCardNumber += 1 creditCardNumber } //測試 def main(args: Array[String]) { //得到新的卡號:通過類名.方法 println(CreditCard.generateNewCCNumber()) println(CreditCard.generateNewCCNumber()) println(CreditCard.generateNewCCNumber()) println(CreditCard.generateNewCCNumber()) } }
運行:
2、應用程序對象: App -----> 可以省略main方法
package main.scala object MainAppObject extends App { //創建一個main方法 // def main(args: Array[String]): Unit = { // println("Hello World") // } println("Hello World") }
七、類的apply方法:省略new關鍵字
舉例:val s1 = new Student
val s2 = Student ---> 必須要定義Student類的apply方法
package main.scala /** * 主構造器 */ class Student5(val stuName:String){ } object Student5 { //定義類的Apply方法 位置:定義在類的伴生對象中 def apply(stuName:String) ={ println("調用到了apply方法") //調用主構造器 new Student5(stuName) } def main(args: Array[String]) { //創建學生對象 var s1 = new Student5("Tom") println(s1.stuName) //省略new 關鍵字 var s2 = Student5("Mary") println(s2.stuName) } }
運行:
八、繼承 extends
子類與父類同名時,需要加override
package main.scala //繼承 /* * 1、基本的繼承 * 2.復寫父類方法 * 2.使用匿名子類 * */ //定義父類 class Person(val name:String,val age:Int){ //方法(函數) def sayHello():String = "Hello " + name + " and the age is "+age; } //定義子類 class Employee(override val name:String,override val age:Int,salary:Int) extends Person(name,age) { //重寫父類中的sayhello override def sayHello():String = "子類中的sayHello方法" } object Demo1 { def main(args: Array[String]): Unit = { //創建一個Person對象 var p1 = new Person("Tom",20) println(p1.sayHello()) //創建一個子類 var p2:Person = new Employee("Mike",25,1000) println(p2.sayHello()) //創建一個匿名子類,從Person繼承 var p3:Person = new Person("jerry",26){ //在匿名子類中重寫父類的方法 override def sayHello():String = "匿名子類中的sayHello方法" } println(p3.sayHello()) } }
運行:
九、抽象類:方法只聲明,不實現
package main.scala //抽象類 //父類: 抽象 交通工具 abstract class Vehicle{ //定義一個抽象方法 def checkType():String } //子類 class Car extends Vehicle{ def checkType():String = {"I am a car"} } class Bike extends Vehicle{ def checkType():String = {"I am a bike"} } object Demo2 { def main(args: Array[String]):Unit = { var v1:Vehicle = new Car var v2:Vehicle = new Bike println(v1.checkType()) println(v2.checkType()) } }
運行:
十、抽象字段:沒有初始值的字段
package main.scala.p1 //父類:抽象 abstract class Person{ //就是一個抽象字段 var id:Int var name:String } //一種做法 abstract class Employee1 extends Person{ //var id:Int = 1 var name:String = "No Name" } //另一種做法: 定義一個主構造器,在主構造器中,提供抽象字段 class Employee2(var id:Int) extends Person{ //只提供name var name:String = "No Name" } class Demo3 { }
十一、特質trait:就是抽象類
與抽象類的最大區別:支持多重繼承 :extends... with
package main.scala.p2 //特質:trait //有點像接口、也有點像抽象類 支持多重繼承 trait Human{ //抽象字段 var id:Int var name:String //方法:可以是抽象,也可以不是 def sayHello():String = "Hello" + name } trait Action{ //定義一個抽象方法 def getActionName():String } //定義一個子類,從上面兩個繼承 //關鍵字: extends... with class Student6(var id:Int,var name:String) extends Human with Action{ //實現Action中的getActionName def getActionName():String = "Action is running" } object Demo4 { def main(args: Array[String]) { var s1 = new Student6(1,"Tom") println(s1.sayHello()) println(s1.getActionName()) } }
運行:
十二、包和包對象
舉例:package ****{
class ****
def 函數
val 常量
等等
}
包可以被引用在程序的任何地方
可以把工具函數或者常量添加到包對象裏,在其他的類裏導入這個包對象就可以引用。
包對象:常量,變量,特質,方法,類,對象
大數據筆記(二十四)——Scala面向對象編程實例