Scala的類、屬性、物件欄位
轉載自:類、屬性、物件欄位
1 類(class)
1.1 定義類
Scala是一種純粹的物件導向程式語言,而又無縫地結合了命令式和函式式的程式設計風格。在物件導向的語言有兩個重要的概念:類(class)和物件(object也被稱為例項—instance),其中類是物件的抽象。可以把類理解為模板,物件才是真正的實體。
程式碼示例:
- class Person() {
- // 定義age 為類私有屬性
- private var age = 0; //必須初始化欄位
- // 定義方法 age +=1,預設方法公有
- defincrement(){age += 1}
- // 將age中的值賦值到current
- def current =age;
- }
- def main(args:Array[String]): Unit = {
- val person = new Person();
- // person.age=10; //私有的不能設定值
- person.increment();
- person.increment();
- println(person.current);
- }
輸出結果:2
1.2 getter/setter方法
類中的欄位自動帶有getter/setter方法。你也可以用定製的getter/setter方法替換掉原來的欄位的字定義,而不必修改使用的客戶端——這就是所謂的“統一訪問原則”。
程式碼示例:
- class Student {
- // 宣告age屬性,預設生成get\set方法,同時預設age是private
- var age = 0;
- //私有的變數只有getter方法沒有setter方法
- // private[this]只能在當前class中使用,不能在其它方法中使用
- private[this] var privateWeight = 120;
- // val private[this]修飾的變數只能當前類使用
- var name = "Scala";
- def weight = privateWeight;
- // 新增 private [this] 關鍵字後只在本類中使用
- // def isFat(other:Student) = privateWeight < other.privateWeight;
- }
- def main(args: Array[String]): Unit = {
- val student = new Student();
- // 賦值時呼叫student.age的set方法 def age_=(x$1: Int): Unit
- student.age =20
- // 呼叫student.age,其實上呼叫get方法:def age: Int
- println(student.age);
- }
輸出結果:20
1.3 主建構函式
Scala中,每個類都有主建構函式,主建構函式並不以this的方式定義,而是與類定義交織在一起,主構造器的引數被編譯成欄位。
程式碼示例:
- class Computer /*主建構函式*/() {
- // 類級別宣告的變數必須賦值
- var display :String ="LED";
- // 私有屬性
- private var price = 3000;
- // 私有屬性,只能在本類中使用
- private[this] var cpu = "四核";
- def this(display:String){
- // 最終都需要呼叫預設this()預設構造
- this();
- this.display =display;
- }
- defsayConfig(){
- println("顯示器:"+this.display+",價格:"+this.price+",cpu:"+this.cpu);
- }
- }
- def main(args:Array[String]): Unit = {
- var computer = new Computer();
- computer.display = "3D";
- computer
- computer.sayConfig();
- }
輸出結果:顯示器:3D,價格:3000,cpu:四核
1.4 輔助建構函式
Scala可以有任意多的建構函式,除主建構函式外還有任意多的輔助構造器:
1.輔助類的構造器的名稱為this(如果與類名相同修改類名的時候不方便)
2.每一個輔助構造器都必須以一個對先前已定義的其它輔助或主構造器的呼叫開始。
程式碼示例:
- class Moblie /*主建構函式*/private /*私有構造器*/(val brand:String,val price:Int){
- // 定義變數
- var networkType :String ="";
- // 過載建構函式
- def this(brand:String,price:Int,networkType:String){
- this(brand,price);
- this.networkType =networkType;
- }
- }
- def main(args: Array[String]): Unit ={
- // // 在建構函式加private修飾,建構函式將不可用
- // var moblie = new Moblie("SAMSUNG",4500);
- // moblie.networkType = "三星"
- //
- // // 在建構函式加private修飾,建構函式將不可用
- // var moblie = new Moblie("SAMSUNG",4500);
- // println("品牌:"+moblie.brand);
- //
- var moblie = new Moblie("SAMSUNG",4500,"3G網路通訊");
- println("品牌:"+moblie.brand);
- println("價格:"+moblie.price);
- println("通訊型別:"+moblie.networkType);
- }
1.5 內部類
Scala可以將一個類定義在另一個類裡面或者一個方法裡面,這樣的類稱為內部類。
程式碼示例:
- // class Outer{outer=>語法使得outer變數指向Outer.this。對這個變數,可以 使用任何合法的名稱。
- class Outer(val name:String){ outer =>
- class Inner(val name:String){
- deffoo(b:Inner) = println("Outer:"+outer.name + ",Inner:"+b.name)
- }
- }
- def main(args:Array[String]): Unit = {
- // scala內部類,隸屬於外部類實體本身
- val outer1 = new Outer("Spark");
- val outer2 = new Outer("Hadoop");
- val inner1 = new outer1.Inner("scala");
- val inner2 = new outer2.Inner("java");
- inner1.foo(inner1);
- inner2.foo(inner2);
- }
Outer:Spark,Inner:scala
Outer:Hadoop,Inner:java
引數生成的欄位及方法:
建構函式 | 生成的欄位方法 |
name:String | 物件私有欄位。如果沒有方法使用name,則沒有該欄位。 |
Private val/var name String | 私有欄位,私有getter/setter方法。 |
Val/var name:String | 私有欄位,公有getter/setter方法 |
2 物件(object)
2.1 伴生物件
在Java或C++中即有例項方法又有靜態方法。在Scala可以通過類與同名的“伴生”物件來達到同樣的目的。
類和它的伴生物件可以互相訪問私有特性。它們必須在於同一個原始檔中。
程式碼示例:
- // 伴生物件(一般情況下,做為伴生類的靜態區域)
- object University {
- private var studentNo = 0;
- def newStudentNo(): Int = {
- studentNo = studentNo + 1
- studentNo
- }
- }
- // 伴生類
- class University {
- var id = University.studentNo;
- private var number = 0;
- def adClass(number: Int) {
- this.number += number;
- }
- }
2.2 apply方法
使用apply方法會省去new關鍵字使用起來更方便。通常apply方法返回的是伴生類的類的物件。
- // 伴生類
- class ApplyTest(){
- def apply() = println("I am into Spark so much!!!");
- def haveAtry(){
- println("Have a try on apply!");
- }
- }
- // 伴生物件-apply中的應用
- object ApplyTest {
- def apply (): ApplyTest = {
- println("I am into Scala to much!!!")
- new ApplyTest
- }
- }
- // 方法呼叫
- object Oop {
- def main(args: Array[String]): Unit = {
- val a = ApplyTest();
- a.haveAtry();
- println(a());
- }
- }
輸出結果:
I am into Scala to much!!!
Have a try on apply!
I am into Spark so much!!!
()
3 物件導向程式設計(OOP)
3.1 scala繼承(extends)
子類繼承父類的特徵和行為,使得子類具有父類的各種屬性和方法。或子類從父類繼承方法,使得子類具有父類相同的行為。
特點:在繼承關係中,父類更通用、子類更具體。父類具有更一般的特徵和行為,而子類除了具有父類的特徵和行為,還具有一些自己特殊的特徵和行為。在繼承關係中。父類和子類需要滿足is-a的關係。子類是父類。
表示父類和子類的術語:父類和子類、超類和子類、基類和派生類。
程式碼示例:
- class Animal(val name:String,val age:Int){
- println("The primaryconstructor of Animal!!!")
- // 顏色-白色
- val color= "white";
- // 睡覺4小時
- def sleep = "4hours";
- // 重寫toString方法
- override deftoString() = "I am a Animal Animal.toString method";
- }
- class Dog(name:String,age:Int,val height:String)
- extends Animal(name,age) {
- println("This is thesubClass of Animal,Primaryconstructor of Dog!!!")
- // 重寫color 屬性
- override val color= "yellow";
- override deftoString() = "I am a Dog !"+ super.sleep;
- }
- //方法呼叫
- def main(args:Array[String]): Unit = {
- val dog = new Dog("Poodle",6,"10cm");
- println(dog.color);
- println(dog.height);
- println(dog.toString());
- }
輸出結果:
The primary constructor of Animal!!!
This is the subClass of Animal,Primary constructor ofDog!!!
yellow
10cm
I am a Dog !4 hours
3.2 抽象類(abstractclass)
使用了關鍵詞abstract宣告的類叫作“抽象類”。如果一個類裡包含了一個或多個抽象方法,類就必須指定成abstract(抽象)。“抽象方法”,屬於一種不完整的方法,只含有一個宣告,沒有方法主體。
程式碼示例:
- // 抽象類
- abstract classSuperTeacher(var name:String){
- // 定義抽象id 屬性
- var id : Int;
- // 定義抽象age 屬性
- var age: Int;
- // 定義抽象teach方法
- def teach;
- }
- /*
- * 實現類TeacherForMaths需要現實抽象類中所有的屬性和方法
- */
- classTeacherForMaths(name:String)extends SuperTeacher(name){
- // 實現 抽象 id 屬性賦值
- override var id =name.hashCode();
- // 實現 抽象 age 屬性賦值
- var age: Int = 25;
- // 實現 抽象 teach 屬性賦值
- def teach:Unit = {
- println("Teaching!!!");
- }
- }
- // 方法呼叫
- defmain(args: Array[String]): Unit = {
- var teacher = newTeacherForMaths("Scala");
- teacher.teach;
- println("teacher.id="+teacher.id);
- println("teacher.age="+teacher.age);
- }
輸出結果:
Teaching!!!
teacher.id=79698214
teacher.age=25
3.3 特徵(trait)
特性封裝方法和欄位定義,然後可以通過將它們混合成類被重用。不同於類繼承,其中每個類都必須繼承只有一個父類,一類可以在任意數量特質混合。
特徵用於通過指定支援的方法的簽名定義的物件型別。Scala中也允許部分實現特性但可能不具有構造引數。trait中可以帶有實現的方法,也可以帶有抽象方法,使用trait的方法是with而混入類中。
程式碼示例:
- trait Logger {
- // 空方法,即方法內部不做任務實現
- deflog(msg:String){}
- }
- /*
- * 控制檯日誌類繼承日誌類
- */
- class ConsoleLogger extends Logger with Cloneable{
- defconsoleLogger(){
- println("It'sme !!!");
- }
- }
- /*
- * 使用trait關鍵字混入日誌
- */
- trait TraitLogger extends Logger {
- override def log(msg:String){
- println("TraitLoggerlog is :" + msg);
- }
- }
- // 程式碼呼叫
- def main(args:Array[String]): Unit = {
- // 子類重寫父類的方法
- var consoleLogger = newConsoleLogger();
- consoleLogger.consoleLogger();
- // trait關鍵字混入
- val traitlogger = newConsoleLogger with TraitLogger
- traitlogger.log("It'sme !!!")
- }
輸出結果:
It's me !!!
TraitLogger log is :It's me !!!
3.4 多重繼承
Scala的類只能夠繼承單一父類,但是如果是特徵的話就可以繼承多個,從結果來看就是實現了多重繼承。
程式碼示例:
- // 定義Human類
- class Human(){
- println("Human");
- }
- // 定義trait特性,繼承Human類
- trait TTeacher extends Human(){
- println("TTeacher");
- // 抽象方法
- def teach
- }
- // 定義trait PianoPlayer繼承Human
- trait PianoPlayer extends Human(){
- println("PianoPlayer");
- defpianoPlayer = {println("I'm playing piano.")}
- }
- // PianoTeacher類,繼承Human類,實現TTeacher特徵、PianoPlayer特徵。
- // 物件在構造時,依次從左向右構造
- class PianoTeacher() extends Human with TTeacher withPianoPlayer {
- // 實現TTeacher中teach方法
- override def teach ={println("I'm training students.")}
- }
3.5 AOP實現
AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,是函數語言程式設計的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
程式碼示例:
- // 定義特徵Action
- trait Action {
- def doAction
- }
- // 被加入的方面,定義一下加入了前置處理和後置處理的特徵TBeforeAfter
- trait TBeforeAfter extends Action {
- // abstractoverride 關鍵字覆蓋預設抽象方法,
- // 實際被執行的是被呼叫的實體類中所定義的方法,實際執行將由子類實現。
- abstract override def doAction{
- // 呼叫super.doAction之前的列印
- println("Initialization");
- // 呼叫super.doAction方法
- super.doAction
- // 呼叫super.doAction之後的列印
- println("Destroyed");
- }
- }
- // Work類實現Action特徵
- class Work extends Action {
- // 實現doAction方法
- override def doAction= println("Working...")
- }
- // 程式碼呼叫
- def main(args:Array[String]): Unit = {
- // 呼叫doAction方法
- val work = new Work withTBeforeAfter;
- work.doAction;
- }
輸出結果:
Initialization
Working...
Destroyed
相關文章
- Scala類的屬性以及物件私有欄位物件
- 深入理解JavaScript類與物件:揭秘類欄位和靜態屬性的妙用,js靜態屬性和例項屬性JavaScript物件JS
- C#通過反射獲取物件屬性,列印所有欄位屬性的值C#反射物件
- [.net 物件導向程式設計基礎] (10) 類的成員(欄位、屬性、方法)物件程式設計
- odoo欄位屬性列舉Odoo
- C#屬性與欄位C#
- MongoDB文件物件欄位屬性合併的2種轉換方法MongoDB物件
- 共有的表單欄位屬性
- ms sql 獲取表欄位的屬性SQL
- Scala 類和物件物件
- scala類和物件物件
- lambda方法引用獲取欄位屬性
- c#之事件_方法_屬性_欄位C#事件
- 利用 alter 語句修改欄位屬性
- jackson根據屬性名動態序列化物件欄位物件
- C#中的屬性和欄位的區別C#
- python中類物件及類屬性的介紹Python物件
- PHP 物件導向 (二)類屬性PHP物件
- odoo ORM研究3 - odoo fields常用的欄位屬性OdooORM
- 理解Python中的類物件、例項物件、屬性、方法Python物件
- 裝備屬性欄位設計和投放詳解
- [JAVA] 只知物件屬性,不知類屬性?就算類答應,static都不答應Java物件
- PG 資料庫查詢欄位屬性的指令碼資料庫指令碼
- 波哥學JAVA,定義類 宣告屬性 建立物件 例項化物件 物件呼叫屬性或者方法Java物件
- 通過java反射,遞迴查詢物件所有屬性,為空也要返回欄位的結構Java反射遞迴物件
- js 物件方法、類方法、原型方法的區別;私有屬性、公有屬性、公有靜態屬性的區別JS物件原型
- GObject的物件屬性GoObject物件
- Object物件的屬性Object物件
- [提問交流]建立模型,新增屬性,欄位型別如何設定2位小數的欄位型別模型型別
- windows域控裡,屬性和欄位對映表Windows
- C#快速入門教程(5)——欄位與屬性C#
- 始終使用屬性(Property),而不是欄位(Data Member)
- C#學習筆記-欄位、屬性、索引器C#筆記索引
- SAP事務碼MM02裡的欄位屬性控制
- Mybatis Plus實體類屬性與表欄位不一致解決方法MyBatis
- javascript原型物件的屬性不能夠覆蓋物件自有屬性JavaScript原型物件
- Kotlin——中級篇(二): 屬性與欄位詳解Kotlin
- c# saf 框架欄位屬性多層巢狀示例C#框架巢狀