
java instanceof範例 在 コバにゃんチャンネル Youtube 的最佳貼文

Search
範例 8.2 Chicken.java. public class Chicken extends Bird { // 擴充Bird類別 private String ... ... <看更多>
#1. Java 快速導覽- instanceof 運算子 - 程式語言教學誌
Java 的instanceof 運算子(instanceof operator) ,測試某一物件是否為另一 ... 教學誌》的範例程式http://pydoing.blogspot.com/ 檔名:instanceofDemo.java 功能: ...
#2. instanceof-判斷物件繼承關係的小指令 - Sam的程式筆記
JAVA 有個判斷用繼承關係方法instanceof 如下public isParent(Object object){ if(object instanceof ArrayLis... ... 範例程式:.
Java 的 instanceof 運算子(instanceof operator) ,測試某一物件是否為另一類別(class) 的子類別(subclass) ,或是某介面(interface) 的實作 ... 運算子, 功能, 範例.
#4. Java:instanceof 運算子用法說明 - 符碼記憶
但因為基本型別不是物件,所以基本型別陣列不會繼承Object[]。 關鍵字:java instanceof, 泛型, boolean, exception, operator, 使用, 用法, string, 效率, null, api, ...
#5. Java :: final/Object/instanceof - OpenHome.cc
在Java SE API 會宣告為 final 的類別或方法,通常與JVM 物件或作業系統 ... 舉例來說,在〈protected/super〉的範例中, SwordsMan 等類別曾定義過 ...
#6. Java instanceof 和Class.isAssignableFrom(Class<?> cls)的區別
例如下面範例,用來檢查兩個物件的型態是否為繼承關係。 public class Main { public static void main(String[] args) { Child child = new Child(); ...
#7. Java 多型和instanceof的使用_實用技巧 - 程式人生
先建立一個父類Animal類: public class Animal{ public void move(){ System.out.println(\
#8. 三元、型態比對運算子- Java備忘筆記 - GitBook
介紹三元運算子的用法及型態比對運算子instanceof。 ... 範例程式: ... 我們在設計Java程式的時候,有時候會想知道這個物件是不是屬於某個類別(class)、某個子 ...
#9. 【Java关键字】理解instanceof关键字 - CSDN博客
instanceof 作用于实例对象、实现类、直接或间接子类; instanceof的实现策略. 了解instanceof. instanceof严格来说是Java中的一个双目运算符,用 ...
#10. 模式比對與多型 - iThome
2021年11月18日 — 以Java來說,不管是現在就支援的instanceof模式比對,或是未來的switch ... 以〈揭露型態邊界的彌封類別〉談到的範例〈代數資料型態:Java 17〉來說, ...
#11. java 判斷類型instanceof,不要再用try catch了- IT閱讀
[摘要:1.之前總是用try catch去判別工具範例,目前要用instanceof了,迥殊是spring integration有比擬多會傳送分歧的payload type if( sth ...
#12. JAVA範例
Java 2 Platform, Standard Edition, v 7 API Specification ... Chapetr7 物件導向設計: 類別與物件範例 ... ch9_11 instanceof運算子 ...
#13. Java Class.isInstance() 方法及程式碼範例
如果對象是當前Class 的範例,則返回 true , 否則返回 false . 說明. 此方法是Java 語言 instanceof 運算符的動態等效方法. 如果指定的 Object 參數爲非 null 並且可以 ...
#14. 第九章介面
9.6 instanceof運算子 ... 範例9-1:ch9_01.java(隨書光碟 ... 範例:. 【觀念範例9-2】:同時繼承類別並實作介面。 範例9-2:ch9_02.java(隨書光碟.
#15. 定義表示式 - IBM
expression instanceof java.class.name 此運算子類似於Java 的 instanceof 運算子,會產生布林值。在此範例中,如果 expression 值所屬的類別符合下列任何條件之一, ...
#16. Java 程式語言教學
Java 語言基於上述理念,定義了Java Virtual Machine,它所用的指令稱為byte code。 ... 的運算符號外, 另外新增了>>>向右無號shift, 以及用來判斷物件型態的instanceof。
#17. java null instanceof的網友經驗文分享跟推薦 - 程式語言代碼
而java myJava.ch02.ch2_01是要求JVM執行ch2_01.class,必. 須在C槽根目錄下執行。 您也可以如同第一章使用兩個Dos視窗分別進行編譯與執行。 本範例之後的執行結果, ...
#18. 給Java 程式設計師的Scala 入門教學
執行範例. 一旦編譯過後,Scala 程式可以用 scala 指令執行。 ... isInstanceOf 對應到Java 的 instanceof 運算子,只在當使用它的物件之型別跟給定型別一樣時傳回真。
#19. 第8 章繼承(Inheritance)、多型(Polymorphism) - GitHub
範例 8.2 Chicken.java. public class Chicken extends Bird { // 擴充Bird類別 private String ...
#20. 12. Inheritance in Java
程式範例: oop_ex113.java. 1. 繼承而產生仍為介面,故新增成員只能是常數與抽象方法。 2. 與類別不同,子介面可繼承多個介面。 12.6 instanceof operator in Java.
#21. 帶你搞懂Java的介面(範例詳解) - tw511教學網
上面的程式碼範例中,提到了instanceof,可能有小夥伴不太理解,我在前面的部落格中有介紹,這裡再重新為大家講解一下 instanceof是Java的一個保留 ...
#22. Java instanceof用法_Mr.madong的技术博客
Java instanceof 用法,instanceof运算符用法运算符是双目运算符, ... if(null instanceof Object){ System.out.println("true"); ... 经典范例:.
#23. 找instance of java相關的社群貼文資訊第9頁
提供instance of java相關的社群貼文資訊,想要了解更多Not instanceof java、java instanceof範例、Instanceof貼文,歡迎來投資貼文懶人包提供您完整相關訊息.
#24. 適合Java 開發人員的Xamarin - Microsoft Learn
如果您是Java 開發人員,您應該已經開始在Xamarin 平台上運用自己的技巧和現有 ... Android 來源檔案開頭看到一連串的 using 陳述式,如此範例所示:.
#25. instanceof關鍵字 - IT145.com
instanceof 是學習java時會遇到的一個二元操作符;所謂二元就是和==,>,<一樣,需要兩個運算元;作用是:判斷左邊物件是否為右邊類的範例;1instanceof ...
#26. Java 教學及程式範例大全
Java :程式執行時間計算 · System.getProperty的參數用法 · Java:instanceof 運算子用法說明. 陣列處理、資料結構如Map、Set、List、排序:.
#27. instanceof判断实例化对象是否_Java面向对象编程_课程笔记
语法:对象instanceof 类判断将返回一个boolean类型,如果是true表示实例是指定类对象。 范例: 如果要执行对象的向下转型,首先要使用instanceof进行 ...
#28. Java 物件導向
語可以是static、abstract 或final 等型態的指定字,實際定義範例為:. MyClass.java 類別定義 public class MyClass{. // MyClass 類別的內容包含了屬性以及方法敘述. }.
#29. typeof - JavaScript - MDN Web Docs
範例 · 一般情況 · null · 正規表示式(Regular expressions) · 其它怪異輸入(quirks) ...
#30. 訪問者模式(Visitor Pattern)
通常遇到這種情情,在Java 中最直接的做法就是使用instanceof 關鍵字來判斷,如以下的簡單範例: public interface CarComponent { public void ...
#31. 繼承與多型學習目標
瞭解繼承目的; 瞭解繼承與多型的關係; 知道如何重新定義方法; 認識java.lang. ... 若用以上的範例來理解,在showBlood()方法中,既可以透過Role型態操作SwordsMan ...
#32. Java裡面as_與Java中的C#關鍵字「 as」等效 - CodeBuug
在Java中,如果轉換失敗,是否可以嘗試進行轉換並回傳null? public static < T > ... 下,不能使B類通用(對於本範例)(這與instanceof不能使用通用型別這一事實有關):.
#33. Kotlin: When. 上週先假設了讀者了解when 表達式
Kotlin 並未提供Java 或C 常見的switch 表達式,反而提供了when 來做case by ... 例如上方隨機產生1 至7 數字的範例, when 裡頭判斷的只有1、2 與3 ,compiler 會要求 ...
#34. Java 泛型 - HackMD
不能 使用instanceof 運算符號,同樣是因為類型擦除後所帶來的副作用,會導致無法判別. 不能使用在靜態,泛型創建對象時才能確定,但靜態方法、參數,是不用加載就可以 ...
#35. Start: Java中對象的類型判斷
判斷一個對象是否是一個類的實例,用Java中自帶的關鍵字instanceof似乎可以做到(僅從關鍵字 ... public abstract class Number implements java.io.
#36. Java-chapter 07: 物件導向進階觀念
參考page 7-3 程式範例 ComputerBook.java ... javac -d obj books\computer\ComputerBook.java ... 參考page 7-26 程式範例 Instanceof.java ...
#37. 重點整理 - Java 學習系列
如以上的範例使用到int 來宣告num為整數變數;如果想同時宣告數個整數變數可以這樣寫:. int num1,num2,num3; // 同時宣告num1,num2,num3 為整數變數 ...
#38. Java instanceof运算符- 经验笔记 - 基础教程(nhooo.com)
instanceof 运算符仅用于对象引用变量。运算符检查对象是否具有特定类型(类类型或接口类型)。instanceof运算符写为-如果运算符左侧变量所引用的对象通过了IS-A检查右 ...
#39. Java基本語法– 歐維斯 - 隨手筆記
運算子, 說明, 範例. instanceof, 判斷某物件(x)是否為某class(y)的instance(或y的子類別的instance), x instanceof y ...
#40. 設計第一個Java程式
為能使讀者熟悉設計開發Java語言最基本的流程,本書的範例程式並不直接 ... final finally float for goto if implements import instanceof int interface long ...
#41. 用於將Servigistics InService 與訂購系統整合的範例程式碼
CommerceDelegate 介面之自訂委派的自訂Java 來源檔案。您可以依照需求來修改這份程式碼。 用於針對訂單可變屬性取得鍵與值的範例程式碼.
#42. 关于java:instanceof运算符会产生很多开销吗? 为什么?
我看到很多代码,其中应该使用OO范例来实现大量的if instanceof语句。 @Bozho,您能提供替代方法而不是使用instanceof来减少开销吗? @Deepak-多态性。访客模式有时。
#43. 使用 JMS 搭配 Amazon SQS 標準佇列實際可行的 Java 範例
以下程式碼範例示範如何使用 Java 訊息服務 (JMS) 搭配 Amazon SQS 標準佇列。 ... getMessage() ); System.exit(3); return; } if( connection instanceof ...
#44. Java String charAt() 方法 - 简单教程
Java String 对象的**charAt()** 方法用于返回指定索引处的字符索引范围为从0 到length() - 1 ## 语法```java ... 下面的范例使用charAt() 方法返回指定位置的字符.
#45. JavaScript 物件導向Object-oriented programming, OOP
JavaScript 是基於Prototype-based 的語言,不像C++ 或Java 等Class-based 的語言有class ... Prototype-based Inheritance Example (繼承實作範例).
#46. [Groovy] 程式設計教學:建立和使用串列(List) | 開源技術教學網
Groovy 的串列是建立在Java 的List 上,但在原本Java 的List 上加上一些語法糖, ... 3 assert list[0] == 1 asset list instanceof java.util.
#47. Lab_Ch_6_8 == , equals 如何使用
下載6-8範例 ... MyDate.java. public class MyDate { private int day; ... if ( (o != null) && (o instanceof MyDate) ) { MyDate d = (MyDate) o;
#48. 王者歸來Java全端技術領航: 從零基激升高超工程師一本通 - 誠品
本書對每個基礎知識都進行了深入分析,針對基礎知識在語法、範例、程式及工作實現上進行階梯式層層強化,讓讀者對基礎知識從入門到靈活運用一步一步腳踏實地進行。 本書的 ...
#49. [Java] instanceof & getClass | 艾斯的軟體學習誌 - - 點部落
[Java] instanceof & getClass · instanceof,除了可以得到物件的型別,也可以得到物件的繼承關係。 · getClass搭配equals,只能判斷物件與類別的直接關係, ...
#50. [java]繼承範例 - nini的部落格
if(t1 instanceof Object). System.out.println("t1's an Object");. } public boolean equals(Object o). {. return this.x==((Inheritance)o).
#51. [2014-3-14]JAVA筆記_多態(Polymophism)、instanceof關鍵字
[2014-3-14]JAVA筆記_多態(Polymophism)、instanceof關鍵字 ... JAVA中面向對象主要有兩種提現:. (1) 方法的重載與覆寫。 ... 範例:對象的向上轉型.
#52. 說明用法二元運算子
範例 :. int x = 6;; double y;. 4. National Taiwan University ... double import public throws byteelse instanceof return transient case extends int short
#53. 【從零開始學Java 程式設計】運算符號 - HKT 線上教室
範例 :將100指定,存到左邊的intVal 變數箱子中。 int intVal = 100;. 算數運算符號. 數學加、減 ...
#54. Java 範例| 線上程式語言教學練習
Java 範例 本章節我們將為大家介紹Java 常用的例項,透過例項學習我們可以更快的掌握Java 的應用。 ... Java 範例- 如何執行指定class檔案目錄(classpath)?
#55. jsp簡單留言板 - 聰明的生活
這個範例有新增留言、查詢留言及留言分頁顯示等功能,後台的管理還沒有建 ... PreparedStatement) obj).close(); else if (obj instanceof java.sql.
#56. Java 程式架構與物件概念
範例 2_6:設有檔案Ex2_6.java,其功能為介紹主體類別程序之地位, ... false、final、finally、float、friend、for、if、implements、import、instanceof、.
#57. 標籤:'instanceof 運算子'相關部落格專區- JAVA366
這篇文章主要介紹了Spring mvc整合mybatis(crud+分頁外掛)操作mysql的步驟詳解,需要的朋友可以參考下一... Java Mysql 操作封裝 ...
#58. Kotlin 實戰範例(6) 類別與物件| Tony Blog
程式設計學習筆記及教學(tutorial),包含網頁程式設計(web)、手機應用程式設計(Android App、iOS App)、程式語言(Java、Kotlin、PHP、Objective ...
#59. 物件導向程式設計– 實習課
範例 :public static void main(String[] args). 此為固定寫法,請同學務必熟記!! 6. 程式類別(CLASS). class:. 在java世界中,即為類似API的存在,以往在c的時後, ...
#60. Java 中instanceof 运算符的使用场景_对数函数的博客
Instanceof 运算符的含义Java 中的instanceof 运算符可以指出对象是否是特定类的一个实例。在具体的语句中 ... pdfAndroid语法范例参考大全,杨明羽编著,P586.pdfASP.
#61. [翻譯] 給Java程式設計師的Scala入門教學- 看板Translate-CS
執行範例一旦編譯過後,Scala程式可以用`scala` 指令執行。 ... isInstanceOf` 對應到Java的`instanceof` 運算子,只在當使用它的物件的型別跟給定型 ...
#62. Adobe Flash Platform * 資料類型
靜態產生類型的語言(如C++ 和Java) 會在編譯階段進行類型檢查;動態產生類型的 ... 下列範例會示範上個範例的相同測試,但是使用的是 instanceof 而不是 is 運算子。
#63. ReflectionToStringBuilder (3) 客製化輸出格式ToStringStyle 範例
[Java] 印出物件內容的好幫手– ReflectionToStringBuilder (3) 客製化輸出 ... Object valueObj) { if (valueObj instanceof Date) // 如果物件是Date ...
#64. Overload (多載) vs. Override (覆寫) - (II) - NotFalse 技術客
若無指明,本篇使用的語言預設為Java。 ... 型別比較運算子(instanceof); if-else 長鍊; Liskov 替代原則 ... 上方的範例,有一個很大的問題:
#65. 使用instanceof 要注意 - minglight - 痞客邦
最常犯的邏輯上的錯誤是沒考慮到null的情形而做instanceof , 卻又要在裡面做null判斷. ex : public void m1(Object s1){. if(s1 instanceof String){.
#66. Map @ 阿葉的JAVA筆記:: 隨意窩Xuite日誌
if(obj instanceof Star){ //檢查Star是否為obj的子類別. Star s=(Star)obj; if(this.name.equals(s.name)&& ... 使用enteySet()取值範例
#67. 多态性(向上转型/向下转型/instanceof) - 简书
多态性(向上转型/向下转型/instanceof) ... 范例:观察向上转型. package 面向对象; class Message ... Exception in thread "main" java.lang.
#68. [ Java 小學堂] Java 世界裡equals 與== 的差別 - 程式扎記
範例 程式: 下面以簡單的範例程式說明equals 與== 的差別: - myObject1.java 代碼: ... (obj instanceof myObject2)) return false;; return this.
#69. 附錄一 JAIN SIP 範例程式-JainSipPhone
"java ". + "examples.JainSipPhone.JainSipPhone \n" ... if (authHeader instanceof ProxyAuthenticateHeader) { ... JMF 範例程式- AVReceive2、AVTransmit2.
#70. [轉錄][SNMP4J] CommandResponderEvent的幾個處理範例
在找資料時剛好看到有文章整理了CommandResponderEvent的幾個範例,覺得不錯趕緊 ... Project: apmrouter File: TrapPrinter.java View source code ...
#71. Java 面向对象(七) - TeHub
范例 : class A{ // 定义类A public void fun1(){ // 定义fun1()方法 ... 在Java中可以使用instanceof关键字判断一个对象到底是哪个类的实例。
#72. Java POI 以Xlsx Excel 為實務範例,包含讀取、寫入及合併欄 ...
Java POI 以Xlsx Excel 為實務範例,包含讀取、寫入及合併欄位舉例 ... 建立寫入Excel 程式範例 ... else if (field instanceof Integer) {.
#73. JAVA與LDAP查詢 - 昕力資訊
程式碼,大部份的驗證就使用該方式就行了,範例是以admin來驗證登入LDAP, ... if(obj instanceof byte[]) { val = new String((byte[]) obj); } ...
#74. Java初探:向上轉型(Upcasting)與向下轉型(Downcasting)
Java 初探:向上轉型(Upcasting)與向下轉型(Downcasting). 2013/07/11. 在之前多型(Polymorphism)的範例中,我們用到的技巧其實就是向上轉型,因此這一篇我們來 ...
#75. Documentation - Typeof Type Operator - TypeScript
This isn't very useful for basic types, but combined with other type operators, you can use typeof to conveniently express many patterns.
#76. Java instanceof运算符 - 易百教程
java 中的 instanceof 也称为类型比较运算符,因为它将类型与实例进行比较。 它返回 true 或 false 。 如果对任何具有 null 值的变量应用 instanceof 运算符,则返回false ...
#77. AJAX and PHP - W3Schools
... and easy to understand Web building tutorials with lots of examples of how to use HTML, CSS, JavaScript, SQL, Python, PHP, Bootstrap, Java, XML and more.
#78. 前后端分离后台基于springboot,shiro,auth2 - 程序员信息网
PrintWriter; import java.util.Properties; /** * Created by fengjian on 2018/7/31. */ public abstract class AbstractTicketValidationFilterImpl extends ...
#79. 第八章繼承 - 林偉川
範例 8_13:異質集合的物件陣列. Page 10. 10. 19 instanceof運算子 instanceof運算式會得到一個布林值,若物件名稱 ... instanceof的優先權和關係運算子的<、>、<=、. > ...
#80. Java instanceof关键字详解 - C语言中文网
在Java 中可以使用instanceof 关键字判断一个对象到底时哪个类的实例,格式如下所示。 对象instanceof 类// 返回boolean类型.
#81. Java 实例– instanceof 关键字用法 - 菜鸟教程
instanceof 是Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean 的数据类型。 以下实例创建了displayObjectClass ...
#82. Java SE 7與Android 4.x程式設計範例教本(第二版)(電子書)
... 參考子類別的物件,但是子類別可能不只一個,所以,Java 提供 instanceof 運算子判斷物件變數是參考到哪一種物件,如下所示: if( s2 instanceof SavingAccount ){ .
#83. Java技术手册, 第五版 - 第 42 頁 - Google 圖書結果
... 而不能與基本資料型別一起使用。 instanceof 的範例如下: " string " instanceof String // True :所有的字串都是 String 實體" " instanceof Object // True :字 ...
#84. Java SE11與Android 9.x程式設計範例教本(電子書)
... 但是子類別可能不只一個,所以,Java 提供 instanceof 運算子判斷物件變數是參考到哪一種物件,如下所示: if ( s2 instanceof SavingAccount ) { .
#85. Java SE 8與Android 5.x程式設計範例教本(電子書)
... 但是子類別可能不只一個,所以,Java 提供 instanceof 運算子判斷物件變數是參考到哪一種物件,如下所示: if( s2 instanceof SavingAccount ){.
#86. Java 深入理解instanceof - 华为云社区
【摘要】 instanceof 是Java 中的一个二元操作符,它的作用是测试左边的对象是否是它右边的类的实例,返回boolean 的数据类型。
#87. 如何更好地理解Java中的instanceof关键字 - 极术社区
instanceof 运算符的前一个操作符是一个引用变量,后一个操作数通常是一个类(可以是接口),用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。
#88. Java关键字(一)——instanceof - YSOcean - 博客园
instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为: ? 1. boolean result = obj instanceof ...
java instanceof範例 在 [翻譯] 給Java程式設計師的Scala入門教學- 看板Translate-CS 的推薦與評價
譯自
https://docs.scala-lang.org/tutorials/scala-for-java-programmers.html
因為原文是用markdown撰寫,譯文也直接用markdown格式撰寫
github好讀版(?)
https://github.com/chikei/scala.github.com/blob/zh_TW/zh/tutorials/
scala-for-java-programmers.md
~~~正文分隔線~~~
## 介紹
此教學將對Scala語言以及編譯器做一個簡易的介紹。設定的讀者為具有程設經驗且想
要看Scala功能概要的人。內文假設讀者有著基本、特別是Java上的物件導向程設知識。
## 第一個例子
這邊用標準的 *Hello world* 程式作為第一個例子。雖然它很無趣,可是這讓我們在
僅用少量語言下演示Scala工具。程式如下:
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
Java程式員應該對這個程式的結構感到熟悉:有著一個 `main` 函式,該函式接受一
個字串陣列引數,也就是命令列引數;函式內容為呼叫已定義好的函式 `println` 並
用Hello world字串當引數。 `main` 函式沒有回傳值(它是程序函式)。因此並不需要
宣告回傳型別。
Java程式員不太熟悉的是包著 `main` 函式的 `object` 宣告。這種宣告引入我們一
般稱之 *Singleton* 的東西,也就是只有一個實體的類別。所以上面的宣告同時宣告
了一個 `HelloWorld` 類別跟一個這類別的實體,也叫做 `HelloWorld`。該實體會在
第一次被使用到的時候即時產生。
眼尖的讀者可能已經注意到這邊 `main` 函式的宣告沒有帶著 `static`。這是因為
Scala沒有靜態成員(函式或資料欄)。Scala程式員將這成員宣告在單實例物件中,而
不是定義靜態成員。
### 編譯這例子
我們用Scala編譯器 `scalac`來編譯這個例子。`scalac` 就像大多數的編譯器一樣,
它接受原碼檔當引數,並接受額外的選項,然後產生一個或多個物件檔。它產出的物
件檔為標準的Java class檔案。
如果我們將上面的程式存成 `HelloWorld.scala` 檔,編譯的指令為( `>` 是提示字
元,不用打):
> scalac HelloWorld.scala
這會在現在的目錄產生一些class檔案。其中一個會叫做 `HelloWorld.class`,裡面
包含著可被 `scala` 直接執行的類別。
### 執行範例
一旦編譯過後,Scala程式可以用 `scala` 指令執行。它的使用方式非常的像執行
Java程式的 `java` 指令,並且接受同樣的選項。上面的範例可以用以下的指令來執
行並得到我們預期的輸出:
> scala -classpath . HelloWorld
Hello, world!
## 與Java互動
Scala的優點之一是它非常的容易跟Java程式碼溝通。預設匯入所有 `java.lang` 底
下之類別,其他類別則需要明確匯入。
讓我們看個展示這點的範例。取得現在的日期並根據某個特定的國家排版成該國的格
式,如法國。
Java的標準函式庫定義了一些有用的工具類別,如 `Date` 跟 `DateFormat`。因為
Scala可以無縫的跟Java互動,這邊不需要以Scala實作同樣的類別--我們只需要匯入
對應的Java套件:
import java.util.{Date, Locale}
import java.text.DateFormat
import java.text.DateFormat._
object FrenchDate {
def main(args: Array[String]) {
val now = new Date
val df = getDateInstance(LONG, Locale.FRANCE)
println(df format now)
}
}
Scala的匯入陳述式跟Java的非常像,但更為強大。如第一行,同一個package下的多
個類別可以用大括號括起來一起導入。另外一個差別是,當要匯入套件或類別下所有
的名稱時,用下標(`_`)而不是星號(`*`)。這是因為星號是一個合法的Scala識別符號
(如函式名稱)。
所以第三行的陳述式導入所有 `DateFormat` 類別的成員。這讓靜態函式
`getDateInstance` 跟靜態資料欄 `LONG` 可直接被使用。
在 `main` 函式中我們先創造一個Java的 `Date` 類別實體,該實體預設擁有現在的
日期。接下來用 `getDateInstance` 函式定義日期格式。最後根據地區化的
`DateFormat` 實體對現在日期排版格式化並印出。最後一行展現了一個Scala有趣的
特點。只需要一個引數的函式可以用中綴語法呼叫。就是說,這個表示式
df format now
是比較不詳細版本的這個表示式
df.format(now)
這點也許看起來只是一個小小的語法細節,但是他有著重要的後果,其中一個將會在
下一節做介紹。
讓我們以,Scala可以直接繼承Java類別跟實作Java介面,來為這節做結尾。
## 萬物皆物件
Scala是一個純粹的物件導向語言,這句話的意思是說,*所有東西*都是物件,包括數
字、函式。因為Java將基本型別跟參照型別分開,而且沒有辦法像操作變數一樣操作
函式,從這角度來看Scala跟Java是不同的。
### 數字是物件
因為數字是物件,他們也有函式。事實上,一個像底下的算數表示式:
1 + 2 * 3 / x
只有使用函式呼叫,因為像前一節一樣,該式等價於
(1).+(((2).*(3))./(x))
這也表示著 `+`、`*` 之類的在Scala裡是合法的識別符號。
因為Scala的詞法分析器對於符號採用最長匹配,在第二版的表示式當中,那些括號是
必要的。也就是說分析器會把這個表示式:
1.+(2)
拆成 `1.`、`+`、`2` 這三個符號。會這樣拆分是因為 `1.` 既是合法匹配同時又比
`1` 長。 `1.` 會被解釋成文字 `1.0`,使得他被視為 `Double` 而不是 `Int`。把
表示式寫成:
(1).+(2)
可以避免 `1` 被解釋成 `Double`。
### 函式是物件
可能令Java程式員更為驚訝的會是,Scala中函式也是物件。因此,將函式當做引數傳
遞、把它們存入變數、從其他函式返回函式都是可能的。能夠像操作變數一樣的操作
函式這點是*函數編程*這一非常有趣的程設典範的基石之一。
為何把函式當做變數一樣的操作會很有用呢,讓我們考慮一個定時函式,它的功能是
每秒執行一些動作。我們要怎麼將這動作傳給它?最直接的便是將這動作視為函式傳
入。應該有不少的程式員對這種簡單傳遞函式的行為很熟悉:通常在使用者介面相關
的程式上,用以註冊一些當事件發生時被呼叫的回呼函式。
在接下來的程式中,定時函式叫做 `oncePerSecond` ,它接受一個回呼函式做參數。
該函式的型別被寫作 `() => Unit` ,這個型別便是所有無引數且無返回值的函式的
型別( `Unit` 這個型別就像是C/C++的 `void` )。此程式的主函式只是呼叫定時函式
並帶入回呼函式,回呼函式輸出一句話到終端上。也就是說這個程式會不斷的每秒輸
出一次"time flies like an arrow"。
object Timer {
def oncePerSecond(callback: () => Unit) {
while (true) { callback(); Thread sleep 1000 }
}
def timeFlies() {
println("time flies like an arrow...")
}
def main(args: Array[String]) {
oncePerSecond(timeFlies)
}
}
值得注意的是,這邊輸出的時候我們使用Scala的函式 `println`,而不是
`System.out` 裡的函式。
#### 匿名函式
這程式還有改進的空間。第一點,函式 `timeFlies` 只是為了能夠被傳遞進
`oncePerSecond` 而定義的。賦予一個只被使用一次的函式名字似乎是沒有必要的,
最好能夠在傳入 `oncePerSecond` 時構造出這個函式。Scala可以藉由*匿名函式*來
達到這點。利用匿名函式的改進版本程式如下:
object TimerAnonymous {
def oncePerSecond(callback: () => Unit) {
while (true) { callback(); Thread sleep 1000 }
}
def main(args: Array[String]) {
oncePerSecond(() =>
println("time flies like an arrow..."))
}
}
這例子中的右箭頭 `=>` 告訴我們有一個匿名函式,右箭頭將函式引數跟函式內容分
開。這個例子中,在箭頭左邊那組空的括號告訴我們引數列是空的。函式內容則是跟
先前的 `timeFlies` 裡一樣。
## 類別
之前已講過,Scala是一個物件導向語言,因此它有著類別的概念。(更精確的說,的
確有一些物件導向語言沒有類別的概念,但是Scala不是這類)。Scala宣告類別的語法
跟Java很接近。一個重要的差別是,Scala的類別可以有參數。這邊用底下複數的定義
來展示:
class Complex(real: Double, imaginary: Double) {
def re() = real
def im() = imaginary
}
這個複數類別接受兩個參數,分別為實跟虛部。在創造 `Complex` 的實體時,必須傳
入這些參數: `new Complex(1.5, 2.3)`。這個類別有兩個函式分別叫做 `re` 跟
`im` 讓我們取得這兩個部分。
值得注意的是,這兩個函式的回傳值並沒有被明確的給定。編譯器將會自動的推斷,
它會查看這些函式的右側並推導出這兩個函式都會回傳型別為 `Double` 的值。
編譯器並不一定每次都能夠推斷出型別,而且很不幸的是我們並沒有簡單的規則分辨
哪種情況能推斷,哪種情況不能。因為當編譯器無法推斷未明確給定的型別時它會回
報錯誤,實務上這通常不是問題。Scala的初學者在遇到那些看起來很簡單就能推導出
型別的情況時,應該嘗試著忽略型別宣告並看看編譯器是不是也覺得可以推斷。多嘗
試幾次之後程式員應該能夠體會到何時忽略型別、何時該明確指定。
### 無引數函式
函式 `re`、`im` 有個小問題,為了呼叫函式,我們必須在函式名稱後面加上一對空
括號,如這個例子:
object ComplexNumbers {
def main(args: Array[String]) {
val c = new Complex(1.2, 3.4)
println("imaginary part: " + c.im())
}
}
最好能夠在不需要加括號的情況下取得實虛部,這樣便像是在取資料欄。Scala完全可
以做到這件事,需要的只是在定義函式的時候*不要定義引數*。這種函式跟零引數函
式是不一樣的,不論是定義或是呼叫,它們都沒有括號跟在名字後面。我們的
`Complex` 可以改寫成:
class Complex(real: Double, imaginary: Double) {
def re = real
def im = imaginary
}
### 繼承與覆寫
Scala中所有的類別都繼承自一個母類別。像前一節的 `Complex` 這種沒有指定的例
子,Scala會暗中使用 `scala.AnyRef`。
Scala中可以覆寫繼承自母類別的函式。但是為了避免意外的覆寫,必須加上
`override` 修飾字來明確表示要覆寫函式。我們以覆寫 `Complex` 類別中來自
`Object` 的 `toString` 作為範例。
class Complex(real: Double, imaginary: Double) {
def re = real
def im = imaginary
override def toString() =
"" + re + (if (im < 0) "" else "+") + im + "i"
}
## Case Class跟模式匹配(pattern matching)
樹是常見的資料結構。如:解譯器跟編譯器內部常見的表示程式方式便是樹;XML文件
是樹;還有一些容器是根基於樹,如紅黑樹。
接下來我們會藉由一個小型計算機程式來看看Scala是如何呈現並操作樹。這個程式的
功能將會是足以操作簡單、僅含有整數、常數、變數跟加法的算術式。`1+2` 跟
`(x+x)+(7+y)`為兩個例子。
我們得先決定這種表示式的表示法。最自然表示法便是樹,其中節點是操作、葉點是
值。
Java中我們會將這個樹用一個抽象母類別表示,然後每種節點跟葉點分別有各自的實
際類別。在函數邊程裡會用代數資料類型。Scala則是提供了介於兩者之間的
*case class*。將它運用在這邊會是如下:
abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
`Sum`、`Var`、`Const` 類別定義成case class代表著它們跟一般類別有所差別:
- 在創建類別實體時不需要用 `new`(也就是說我們可以寫 `Const(5)`,而不是
`new Const(5)`)。
- 對應所有的建構式參數,Scala會自動定義對應的取值函式(即,對於 `Const` 類別
的實體,我們可以直接用 `c.v` 來取得建構式中的 `v` 參數)。
- `equals` 跟 `hashCode` 會有預設的定義。該定義會根據實體的*結構*而不是個別
實體的識別來運作。
- `toString` 會有預設的定義。會印出"原始型態"(即,`x+1` 的樹會被印成
`Sum(Var(x),Const(1))`)。
- 這些類別的實體可以藉由*模式匹配*來拆解。
現在我們有了算術表示式的資料型別,可以開始定義各種運算。我們將從一個可以在
*環境*內對運算式求值的函式起頭。環境的用處是賦值給變數。舉例來說,運算式
`x+1` 在一個將 `x` 賦與 `5` 的環境(寫作 `{ x -> 5 }` )下求值會得到 `6`。
因此我們需要一個表示環境的方法。當然我們可以用一些像是雜湊表的關連性資料結
構,但是我們也可以直接用函式!環境就只是一個將值對應到(變數)名稱的函式。之
前提到的環境 `{ x -> 5 }` 在Scala中可以簡單的寫作:
{ case "x" => 5 }
這串符號定義了一個當輸入是字串 `"x"` 的時候回傳整數 `5`,其他輸入則是用例外
表示失敗的函式。
開始實作之前,讓我們先給環境型別一個名字。當然,我們可以直接用
`String => Int`,但是給這型別名字可以讓我們簡化程式,而且在未來要改動的時
候較為簡便。在Scala我們是這樣表示這件事:
type Environment = String => Int
於是型別 `Environment` 便可以當做輸入 `String` 回傳 `Int` 函式的型別的代名。
現在我們可以給出求值函式的實作。概念上非常的簡單:兩個表示式和的值是兩個表
示式值的和;變數的值直接從環境取值;常數的值就是常數本身。表示這些在Scala裡
並不困難:
def eval(t: Tree, env: Environment): Int = t match {
case Sum(l, r) => eval(l, env) + eval(r, env)
case Var(n) => env(n)
case Const(v) => v
}
這個求值函式藉由對樹 `t` 做*模式匹配*來求值。上述實作的意思應該從直觀上便很
明確:
1. 首先檢查樹 `t` 是否為 `Sum`,如果是的話將左/右側子樹綁定到新變數 `l`/`r`
,然後再對箭頭後方的表示式求值;這一個表示式可以使用(而且這邊也用到)根據
箭頭左側模式所綁定的變數,也就是 `l` 跟 `r`,
2. 如果第一個檢查失敗,也就是說樹不是 `Sum`,接下來檢查 `t` 是否為 `Var`,
如果是的話將 `Var` 所帶的名稱綁定到變數 `n` 並求值右側的表示式,
3. 如果第二個檢查也失敗,表示樹不是 `Sum` 也不是 `Var`,那便檢查是不是
`Const`,如果是的話將 `Const` 所帶的名稱綁定到變數 `v` 並求值右側的表
示式,
4. 最後,如果全部的檢查都失敗,會丟出例外表示匹配失敗;這只會在有更多
`Tree` 的子類別的情況下發生。
如上,模式匹配基本上就是嘗試將一個值對一系列的模式做匹配,並在一個模式成功
的匹配時抽取並命名該值的各部分,最後對一些程式碼求值,而這些程式碼通常會利
用被命名到的部位。
一個經驗豐富的物件導向程式員也許會疑惑為何我們不將 `eval` 定義成 `Tree` 類
別跟子類的*函式*。由於Scala允許在case class中跟一般的類別一樣定義函式,事實
上我們可以這樣做。要用模式匹配或是函式只是品味的問題,但是這會對擴充性有重
要的影響。
- 當使用函式的時候,只要定義新的 `Tree` 子類便新增新的節點,相當的容易。另
一方面,增加新的操作需要修改所有的子類,很麻煩。
- 當使用模式匹配的時候情況則反過來:增加新節點需要修改所有對樹做模式匹配的
函式將新節點納入考慮;增加新的操作則很簡單,定義新的函式就好。
讓我們定義新的操作以更進一步的探討模式匹配:對符號求導數。讀者們可能還記得
這個操作的規則:
1. 和的導數是導數的和
2. 如果是對變數 `v` 取導數,變數 `v` 的導數是1,不然就是0
3. 常數的導數是0
這些規則幾乎可以從字面上直接翻成Scala程式碼:
def derive(t: Tree, v: String): Tree = t match {
case Sum(l, r) => Sum(derive(l, v), derive(r, v))
case Var(n) if (v == n) => Const(1)
case _ => Const(0)
}
這個函式引入兩個關於模式匹配的新觀念。首先,變數的 `case` 運算式有一個
*看守*,也就是 `if` 關鍵字之後的表示式。除非表示式求值為真,不然這個看守會
讓匹配直接失敗。在這邊是用來確定我們只在取導數變數跟被取導數變數名稱相同時
才回傳常數 `1`。第二個新特徵是可以匹配任何值的*萬用字元* `_`。
我們還沒有探討完模式匹配的全部功能,不過為了讓這份文件保持簡短,先就此打住
。我們還是希望能看到這兩個函式在真正的範例如何作用。因此讓我們寫一個簡單的
`main` 函數,對表示式 `(x+x)+(7+y)` 做一些操作:先在環境
`{ x -> 5, y -> 7 }` 下計算結果,然後在對 `x` 接著對 `y` 取導數。
def main(args: Array[String]) {
val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y")))
val env: Environment = { case "x" => 5 case "y" => 7 }
println("Expression: " + exp)
println("Evaluation with x=5, y=7: " + eval(exp, env))
println("Derivative relative to x:\n " + derive(exp, "x"))
println("Derivative relative to y:\n " + derive(exp, "y"))
}
執行這程式,得到預期的輸出:
Expression: Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y)))
Evaluation with x=5, y=7: 24
Derivative relative to x:
Sum(Sum(Const(1),Const(1)),Sum(Const(0),Const(0)))
Derivative relative to y:
Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))
研究這輸出我們可以發現,取導數的結果應該在輸出前更進一步的化簡。用模式匹配
實作一個基本的化簡函數是一個很有趣(但是意外的棘手)的問題,在這邊留給讀者當
練習。
## 特質(Traits)
除了由母類別繼承行為以外,Scala類別還可以從一或多個*特質*導入。
對一個Java程式員最簡單去理解特質的方式應該是視他們為帶有實作的介面。在Scala
裡,當一個類別繼承特質時,他實作了該特質的介面並繼承所有特質帶有的功能。
為了理解特質的用處,讓我們看一個經典範例:有序物件。大部分的情況下,一個類
別所產生出來的物件之間可以互相比較大小是很有用的,如排序他們。在Java裡可比
較大小的物件實作 `Comparable` 介面。在Scala中藉由定義等價於 `Comparable`
的特質 `Ord`,我們可以做的比Java稍微好一點。
當在比較物件的大小時,有六個有用且不同的謂詞(predicate):小於、小於等於、等
於、不等於、大於等於、大於。但是把六個全部都實作很煩,尤其是當其中有四個可
以用剩下兩個表示的時候。也就是說,(舉例來說)只要有等於跟小於謂詞,我們就可
以表示其他四個。在Scala中這些觀察可以很漂亮的用下面的特質宣告呈現:
trait Ord {
def < (that: Any): Boolean
def <=(that: Any): Boolean = (this < that) || (this == that)
def > (that: Any): Boolean = !(this <= that)
def >=(that: Any): Boolean = !(this < that)
}
這份定義同時創造了一個叫做 `Ord` 的新型別,跟Java的 `Comparable` 介面有著同
樣的定位,且給了一份以第一個抽象謂詞表示剩下三個謂詞的預設實作。因為所有的
物件預設都有一份等於跟不等於的謂詞,這邊便沒有定義。
上面使用了一個 `Any` 型別,在Scalla中這個型別是所有其他型別的母型別。因為它
同時也是基本型別如 `Int`、`Float`的母型別,可以將其視為更為一般化的Java
`Object` 型別。
因此只要定義測試相等性跟劣性的謂詞,並且加入 `Ord`,就可以讓一個類別的物件
們互相比較大小。讓我們實作一個表示陽曆日期的 `Date` 類別來做為例子。這種日
期是由日、月、年組成,我們將用整數來表示這三個資料。因此我們可以定義 `Date`
類別為:
class Date(y: Int, m: Int, d: Int) extends Ord {
def year = y
def month = m
def day = d
override def toString(): String = year + "-" + month + "-" + day
這邊要注意的是宣告在類別名稱跟參數之後的 `extends Ord`。這個語法宣告了
`Date` 繼承 `Ord` 特質。
然後我們重新定義來自 `Object` 的 `equals` 函式好讓這個類別可以正確的根據每
個資料欄來比較日期。因為在Java中 `equals` 預設實作是直接比較實際物件本身,
並不能在這邊用。於是我們有下面的實作:
override def equals(that: Any): Boolean =
that.isInstanceOf[Date] && {
val o = that.asInstanceOf[Date]
o.day == day && o.month == month && o.year == year
}
這個函式使用了預定義函式 `isInstanceOf` 跟 `asInstanceOf`。`isInstanceOf`
對應到Java的 `instanceof` 運算子,只在當使用它的物件的型別跟給定型別一樣時
傳回真。 `asInstanceOf` 對應到Java的轉型運算子,如果物件是給定型別的實體,
該物件就會被視為給定型別,不然就會丟出 `ClassCastException` 。
最後我們需要定義測試劣性的謂詞如下。
def <(that: Any): Boolean = {
if (!that.isInstanceOf[Date])
error("cannot compare " + that + " and a Date")
val o = that.asInstanceOf[Date]
(year < o.year) ||
(year == o.year && (month < o.month ||
(month == o.month && day < o.day)))
}
這邊使用了另外一個預定義函式 `error`,它會丟出帶著給定錯誤訊息的例外。這便
完成了 `Date` 類別。這個類別的實體可被視為日期或是可比較物件。而且他們通通
都定義了之前所提到的六個比較謂詞: `equals`跟`<` 直接出現在類別定義當中,其
他的則是繼承自 `Ord` 特質。
特質在其他場合也有用,不過詳細的探討它們的用途並不在本文件目標內。
## 泛型
在這份教學裡,我們最後要探討的Scala特性是泛型。Java程式員應該相當的清楚在
Java 1.5之前缺乏泛型所導致的問題。
泛型指的是能夠將型別也作為程式參數的功能。舉例來說,當程式員在為鏈結串列寫
函式庫的時候,他必須決定串列的元素型別為何。由於這串列是要在許多不同的場合
使用,不可能決定串列的元素型別為如 `Int` 一類。這樣限制太多。
Java程式員採用所有物件的母類別 `Object`。這個解決辦法並不理想,一方面這並不
能用在基礎型別(`int`、`long`、`float`之類),再來這表示必須靠程式員手動加入
大量的動態轉型。
Scala藉由可定義泛型類別(跟函式)來解決這問題。讓我們藉由最簡單的類別容器來檢
視這點:參照,它可以是空的或者指向某型別的物件。
class Reference[T] {
private var contents: T = _
def set(value: T) { contents = value }
def get: T = contents
}
類別 `Reference` 帶有一個型別參數 `T`,這個參數會是容器內元素的型別。此型別
被用做 `contents` 變數的型別、 `set` 函式的引數型別、 `get` 函式的回傳型別。
上面的程式碼使用的Scala的變數語法,應該不需要過多的解釋。值得注意的是賦與該
變數的初始值是 `_`,該語法表示預設值。數值型別的預設值是0,`Boolea8n` 型別
是偽, `Unit` 型別是 `()` ,所有的物件型別是 `null`。
為了使用 `Reference` 類型,我們必須指定 `T`,也就是這容器所包容的元素型別。
舉例來說,創造並使用該容器來容納整數,我們可以這樣寫:
object IntegerReference {
def main(args: Array[String]) {
val cell = new Reference[Int]
cell.set(13)
println("Reference contains the half of " + (cell.get * 2))
}
}
如例子中所展現,並不需要先將 `get` 函式所回傳的值轉型便能當做整數使用。同時
因為被宣告為儲存整數,也不可能存除了整數以外的東西到這一個容器中。
## 結語
本文件對Scala語言做了快速的概覽並呈現一些基本的例子。對Scala有更多興趣的讀
者可以閱讀有更多進階範例的 *Scala By Example*,並在需要的時候參閱
*Scala Language Specification*。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 211.72.92.133
... <看更多>