2018年11月30日 星期五

Java SE 入門教學 - 泛型(Generic)

更新時間:11/30/2018

前言

泛型((Generic)在 JAVA 中有很重要的地位,在物件導向編程及各種設計模式中有非常廣泛的應用。

什麼是泛型?為什麼要使用泛型?

泛型,即「參數化型態」。一提到參數,最熟悉的就是定義方法時形式參數(formal parameter, parameter, 參數),然後調用此方法時傳遞實際參數(actual parameter, arguments, 引數)。那麼參數化型態怎麼理解呢?顧名思義,就是將型態由原來具體的型態參數化,類似於方法中的變數參數,此時型態也定義成形式參數(可以稱之為形式型態參數),然後在使用/調用時傳入具體的型態(實際型態參數)。

泛型的本質是為了參數化型態(在不創建新型態的情況下,通過泛型指定的不同型態來控制形式參數具體限制的型態)。也就是說在泛型使用過程中,操作的數據型態被指定為一個參數,這種參數型態可以用在類別、介面和方法中,分別被稱為泛型類別(Generic Class)、泛型介面(Generic Interface)、泛型方法(Generic Method)。



一、沒有泛型會怎樣?

先看下面這段代碼,我們實現兩個能夠設置點座標的類別,分別設置 Integer 型態的點座標和 Float 類型的點座標:

那現在有個問題:大家有沒有發現,他們除了變數型態不一樣,一個是 Integer,一個是 Float 以外,其它並沒有什麼區別!那我們能不能合併成一個呢?

2018年11月26日 星期一

Java SE 入門教學 - 內部類別-巢狀類別

更新時間:11/26/2018

前言

如果要把每個功能都分出來,一個大型專案肯定會使用超多的類別,但,有時候這個類別只有特定的類別使用時,可以考慮使用另一個技術「內部類別(Inner Class)」、「巢狀類別(Nested Class)」。

內部類別通常是用來輔助外部類別,另一層封裝的類別階層組織,以提高程式的可讀性和維護性。



一、內部類別的基礎概念

在類別中您還可以定義類別,稱之為內部類別(Inner class)或「巢狀類別」(Nested class)。非 "static" 的內部類別可以分為三種:成員內部類別(Member inner class)、區域內部類別(Local inner class)與匿名內部類別(Anonymous inner class);static 的內部類別只有一種:靜態成員內部類別。

使用內部類別的好處在於可以直接存取外部類別的私用(private)成員,舉個例子來說,在視窗程式中,您可以使用內部類別來實作一個事件傾聽者類別,這個視窗傾聽者類別可以直接存取視窗元件,而不用透過參數傳遞。

另一個好處是,當某個 Slave 類別完全只服務於一個 Master 類別時,我們可以將之設定為內部類別,如此使用 Master 類別的人就不用知道 Slave 的存在。

存取修飾子的使用:

外部類別只能使用:public、default、final、abstract。
內部類別可以使用:private、protected、public、static。

2018年11月23日 星期五

Java SE 入門教學 - 匿名物件

更新時間:11/23/2018

前言

物件導向 的文章中有介紹一個類別的基本構成,而當我們使用一個類別建立起一個非靜態的類別時,總是使用建構子來建構「物件實例」,然後儲存在一個「物件參考變數」中;但有時候我們只是想要執行一下這個類別的功能,而後續就再也不使用它了,那麼我還需要管理這個「物件參考變數」嗎?


一、複習:建立一個物件實例

首先,複習一下語法:

父類別(介面)名稱 物件參考變數 = new 自己/子類別建構子();
(i) (ii) (iii)

(i):宣告物件參考變數的型別

(ii):物件參考變數的名字

(iii):建立物件實例

使用 new 關鍵字在記憶體堆區塊(Heap)開闢足夠大的空間建立 自己/子類別 的物件實例。


2018年11月22日 星期四

Java SE 入門教學 - 列舉 Enumeration

更新時間:11/22/2018

前言

程式中經常會使用到一些常數,如果有些常數是共用的,在 Java 中可以定義一個類別或介面來統一管理常數,而其它物件從這些類別或介面上取用常數,如果需要修改常數則可以從這些類別或介面上直接修改,而不用更動到程式的其它部份,這種使用常數的方式在 J2SE 1.4 或之前的版本相當常見。

J2SE 5.0 中新增了「列舉型態」(Enumerated Types),您可以使用這個功能取代之前 J2SE 1.4 或之前版本定義常數的方式,除了常數設置的功能之外,列舉型態還給了您許多編譯時期的檢查功能,但別想的太複雜,列舉型態本質上還是以類別的方式存在,因而它提供了這麼多額外的功能並不奇怪。


一、列舉常數值

在日常生活中,項目固定、值固定,請用列舉。列舉必須寫在類別內部,屬於內部類別。

語法:

enum 列舉名稱{常數值1, 常數值2, 常數值3, ...}

編譯器會自動加上存取修飾值 public static final


範例:星期

安裝 DJ Java Decompiler

更新時間:07/25/2019

前言

想要看 Java 編譯器為我們做了多少事情,就使用「反組譯器」來查看看吧!


一、從網頁下載安裝檔案

▼ 開啟 DJ Java Decompiler 官網,點選【Download for Windows】。

Java SE 入門教學 - 可變動參數與陣列

更新時間:11/22/2018

前言

在寫方法時,我們有時候會使用到相同型別,但參數個數不同的時候,就會使用到多載(Overloading)或是傳入陣列解決問題。

當需要 1個、2個和3個相同型別參數時,使用多載可以解決;使用陣列在操作上就顯得有點麻煩。

public double average(int x){...};
public double average(int x1, int x2){...};
public double average(int x1, int x2, int x3){...};

當100個相同型別參數時,使用多載就必須要寫100個方法,萬一之後要修改,也要修改100個方法,這...太累人了!
所以,使用參數傳入陣列可以省事多了!只是每一次要使用前都要先建立陣列。

public double average(int[] x){...};

當如果要使用 1 ~ 20 個相同型別參數時,該使用多載還是使用陣列呢?這時可以考慮使用可變動參數的寫法,擁有相同型別但數量不同的參數。

2018年11月20日 星期二

Java SE 入門教學 - Object 類別的常見方法

更新時間:11/20/2018

前言

Object 類別是所有類別的根,也就是說當您自己撰寫任何類別的時候,都一定會繼承 Object 類別內的東西,這些東西還真是形影不離啊......。既然每個地方都可以看見它們的存在,勢必要好好「瞭解」與「利用」這些好~夥伴!

方法名稱 方法說明
protected Object clone() 複製此物件。
boolean equals(Object obj) 比較兩個物件是否相等。
protected void finalize() 如果物件沒有任何參考指向它,則會呼叫垃圾收集器(garbage collector)回收。
Class<?> getClass() 取得此物件執行時期的類別。
int hashCode() 雜湊值。
String toString() 回傳代表此物件的字串說明。
void notify() 喚醒正在此物件監視上等待的單個線程。
void notifyAll() 喚醒等待此物件監視上等待的所有線程。
void wait() 導致當前線程等待,直到另一個線程調用此物件的 notify() 方法或 notifyAll() 方法。
void wait(long timeout) 導致當前線程等待,直到另一個線程調用此物件的 notify() 方法或 notifyAll() 方法,或者已經過了指定的時間量。
void wait(long timeout, int nanos) 導致當前線程等待,直到另一個線程為此對象調用 notify() 方法或 notifyAll() 方法,或者某個其他線程中斷當前線程,或者已經過了指定的時間量。

Java SE 入門教學 - 多型

更新時間:11/20/2018

前言

如果類別與類別之間有繼承關係,則您可以用父類別宣告一個參考名稱,並讓其參考至子類別的物件實例,並以父類別上的公開介面來操作子類別上對應的公開方法,這是多型的基本操作方式。


一、多型的基本概念

多型是指在執行期間(而非編譯時期) 判斷物件實例所參考的實際類型,根據其實際的類型調用其相應的方法。

在之前「抽象類別與介面」篇章中,有提到 多型(polymorphism) 的基本概念。



2018年11月18日 星期日

Java SE 入門教學 - 打包JAR

更新時間:11/18/2018

前言

要完成一個 Java 專案,勢必得分好幾個 Class 撰寫。但是當這個 Java 專案完成後,要如何拿給使用者執行呢?總不能讓使用者自己一個一個去試這堆 Class 中到底哪個是擁有程式進入點的 Main Class 吧?Java JDK 提供了將 .class 打包為 .jar 的指令,只要安裝好 JDK 後就可以使用「jar」指令來將 class 檔案打包為以 ZIP 格式壓縮的 JAR 檔案,之後將這 JAR 檔案拿到任何裝有 JRE 的作業系統上,都可以使用「java -jar」指令來執行。


一、JAR(檔案格式)

在軟體領域,JAR 檔案(Java 歸檔,英語:Java ARchive)是一種軟體包檔案格式,通常用於聚合大量的 Java 類別檔案、相關的元資料和資源(文字、圖片等)檔案到一個檔案,以便分發 Java 平台應用軟體或庫。

JAR 文件格式提供了許多好處:

  • 安全性:您可以對 JAR 文件的內容進行數字簽名(digitally sign)。然後,識別您的簽名的用戶可以選擇授予您原本不具備的軟件安全權限。
  • 減少下載時間:如果您的 applet 捆綁在 JAR 文件中,則可以在單個 HTTP 事務中將 applet 的類文件和相關資源下載到瀏覽器,而無需為每個文件打開新連接。
  • 壓縮:JAR 格式允許您壓縮文件以實現高效存儲。
  • 擴展包裝:擴展框架提供了一種向Java核心平台添加功能的方法,JAR文件格式定義了擴展的包裝。通過使用JAR文件格式,您也可以將軟件轉換為擴展名。
  • 套件密封:可以選擇密封存儲在 JAR 文件中的套件,以便套件可以強制實現版本一致性。在 JAR 文件中封裝套件意味著必須在同一個 JAR 文件中找到該套件中定義的所有類。
  • 套件版本控制:JAR 文件可以保存有關其包含的文件的數據,例如供應商和版本信息。
  • 可移植性:處理 JAR 文件的機制是 Java 平台核心 API 的標準部分。

常見的 JAR 文件操作:

操作說明 指令
建立 JAR 檔案 jar cf jar-file input-file(s)
查看 JAR 檔案的內容 jar tf jar-file
提取 JAR 檔案的內容 jar xf jar-file
從 JAR 檔案中提取特定文件 jar xf jar-file archived-file(s)
執行打包為 JAR 檔案的應用程序
(需要 Main-class manifest header)
java -jar app.jar
調用打包為 JAR 檔案的 applet <applet code=AppletClassName.class
    archive="JarFileName.jar"
    width=width height=height>
</applet>

2018年11月17日 星期六

安裝 Dev-C++


更新時間:11/17/2018

前言

這次一款小而巧的 C++ 編譯軟體。
Dev-C++ 是一套用於開發 C/C++ 的自由的整合式開發環境(IDE),並以 GPL 作為散布許可。使用 MinGW 及 GDB 作為編譯系統與除錯系統。Dev-C++ 的 IDE 是利用 Delphi 開發的。
Dev-C++ 是一個 SourceForge 的計畫,是由 Colin Laplace 這位程式設計師及其公司 Bloodshed Software 所開始的。目前 Dev-C++ 一般用於撰寫執行於 Microsoft Windows 的程式。

2018年11月16日 星期五

Java SE 入門教學 - Package部屬

更新時間:11/19/2018

前言

當您專案的類別越寫越多時,需要有一套方式可以管理類別,就像您使用類別管理變數、方法一樣,分門別類。例如在程式中,您也許會定義一個 Rectangle 類別,但另一個與您合作開發程式的開發人員並不曉得已經有這個類別名稱的存在,他可能也定義了一個 Rectangle 類別,於是編譯過後他的 Rectangle 類別檔案會覆蓋您的 Rectangle 類別檔案,問題就發生了。


一、什麼是套件(Package)

套件是 JAVA 用來組織類別、抽象類別、介面與子套件的機制。其作用如下:

  • 防止命名衝突。例如可以有相同類別的名字 Employee 在不同的套件 college.staff.cse.Employee 和 college.staff.ee.Employee 中。
  • 類別(class)、抽象類別(abstract method)、介面(interface)、列舉(enumerations)、註解(annotations)變得更容易搜尋、配置與使用。
  • 存取修飾子發揮作用,可控制訪問權限。
  • 套件可以被視為數據封裝或數據隱藏。

我們必須把相關的類別放在套件中。如此,我們可以簡單地寫上 import 關鍵字導入已經存在的套件包,並在我們的程序中使用它。套件包是一組相關類別的容器,其中一些類別是可訪問的,而其他類別是為內部目的而保留的。我們可以在程序中盡可能地重複使用套件包中已經存在的類別。

2018年11月14日 星期三

Java SE 入門教學 - 例外處理

更新時間:11/19/2018

前言

程式在執行時,有時候會碰到一些狀況使得程式崩潰,這是程式設計師最不想要遇到的狀況。所以 JAVA 提供一些方式可以處理這些狀況,讓程式更穩定。

一、例外的概念

例外指的是運行期出現的錯誤,也就是當程序開始執行以後執行期出現的錯誤。出現錯誤時觀察錯誤的名字和行號最為重要。

Java 例外是 Java 提供用於處理程序中異常的一種機制。

所謂錯誤是指在程序運行的過程中發生的一些例外事件(如:除0溢出,數組下標越界,所要讀取的文件不存在)。

設計良好的程序應該在例外發生時提供處理這些錯誤的方法,使得程序不會因為異常的發生而阻斷或產生不可預見的結果。

Java 程序的執行過程中如出現例外事件,可以生成一個例外物件實例,該例外物件實例封裝了例外事件的信息並將被提交給 Java 執行程序,這個過程稱為拋出(throw)例外。

當 Java 執行程序接收到例外物件實例時,會尋找能處理這一例外的代碼並把當前例外物件實例交給其處理,這一過程稱為捕獲(catch)例外。

2018年11月13日 星期二

Java SE 入門教學 - 抽象類別與介面

更新時間:11/19/2018

前言

前一篇介紹了物件導向,類別的構造與性質,雖然知道把具體或概念一一抽象出來成為類別,碰到相似的具體或概念時,可以使用繼承來減少程式碼的撰寫,但有沒有可能您寫的父類別,繼承過來的子類別卻需要把每個方法都覆寫(Override)一次,導致父類別的方法完全無用武之地呢?

或是您可能想要繼承爸爸與媽媽的意志,爸爸是由爺爺、奶奶這個血脈傳承下來,而媽媽卻是由外公、外婆這個血脈傳承下來,那麼我要如何同時繼承兩個呢?在 JAVA 中規定不能繼承兩個類別,那怎麼辦?

一、抽象類別(abstract class)

既然父類別的方法無用武之地,那麼我們只宣告方法名稱而不實作當中的邏輯,這樣的方法稱之為「抽象方法」(Abstract method)

如果一個類別中包括了抽象方法,則該類別稱之為「抽象類別」(Abstract class),抽象類別是個未定義完全的類別,所以它不能被用來生成物件,它只能被擴充,並於擴充後完成未完成的抽象方法定義。

在 Java 中要宣告抽象方法與抽象類別,使用"abstract"關鍵字。

從某種意義上來說,抽象方法就是被用來重寫的,所以在父類別宣告的抽象方法一定要在子類別裡面重寫。如果真的不想在子類別裡面重寫這個方法,那麼可以在子類別裡面把這個方法再定義為抽象方法,因為子類別覺得我去實現也不合適,應該讓繼承我的子類別去實現比較合適,因此也可以在繼承這個子類別的下一個子類別裡面重寫父類別宣告的抽象方法,這樣是可以的。

2018年11月7日 星期三

Java SE 入門教學 - 物件導向

更新時間:11/07/2018

前言

在現代意義上的物件導向編程中引用「物件」和「導向」的術語在20世紀50年代末和60年代初首次出現在麻省理工學院。早在1960年人工智能組的環境中,「物件」就可以指具有屬性(properties, attributes)的識別項(LISP原子);Alan Kay 後來引用了對LISP內部的詳細理解,對他1966年的思想產生了強烈的影響。

在1960年的 Simula 語言中即可發現,當時的程式設計領域正面臨著一種危機:在軟硬體環境逐漸複雜的情況下,軟體如何得到良好的維護?物件導向程式設計在某種程度上通過強調可重複性解決了這一問題。1970年代的 Smalltalk 語言在物件導向方面堪稱經典——以至於多年後的今天依然將這一語言視為物件導向語言的基礎。

Smalltalk 的建立者深受 Simula 67 的主要思想影響,但 Smalltalk 中的物件是完全動態的——它們可以被建立、修改並銷毀,這與 Simula 中的靜態物件有所區別。此外,Smalltalk 還引入了繼承性的思想,它因此一舉超越了不可建立實體的程式設計模型和不具備繼承性的 Simula。

物件導向程式設計在1980年代成為了一種主導思想,這主要應歸功於 C++ —— C語言的擴充版。在圖形化使用者介面(GUI)日漸崛起的情況下,物件導向程式設計很好地適應了潮流。

James Gosling,Mike Sheridan 和 Patrick Naughton 於1991年6月發起了 Java 語言項目。Java 最初是為交互式電視而設計的,但它對於當時的數字有線電視行業來說太先進了。這種語言最初被稱為 Oak(橡樹),源於 Gosling 辦公室外的一棵 Oak。後來這個項目名為 Green,最後改名為 Java,來自 Java coffee。Gosling 使用 C / C ++ 風格的語法設計 Java,系統和應用程序程序員會覺得這種語法很熟悉。Sun Microsystems 於1996年發行 Java 1.0。

一、函數導向和物件導向的思想

物件導向和函數導向的思想有著本質上的區別,做為物件導向的思維來說,當您拿到一個問題時,您分析這個問題不在是第一步先做什麼,第二步再做什麼,這是物件導向的思維,您應該分析這個問題裡面有哪些類別和物件,這是第一點,然後再分析這些類別和物件應該具有那些屬性和方法,這是第二點。最後分析類別和類別之間具體有什麼關係,這是第三點。

物件導向有一個非常重要的設計思維:合適的屬性與方法應該出現在合適的類別裡面。

2018年11月1日 星期四

Java SE 入門教學 - 陣列

更新時間:11/01/2018

前言

如果要管理一個班級的成績,班級人數有30人,那麼我需要建立30個名字變數,30個國文成績,30個數學成績,30個英文成績等等...,光是宣告變數就要上百個,那...我需要怎麼管理程式?!

一、陣列的基本概念

陣列可以看成是多個相同類型數據組合,對這些數據的統一管理,數據類型可以是「基本型態」或「類別型態」。

陣列的元素起始位置從 0 開始,依序遞增(0, 1, 2, ...)。

二、一維陣列

JAVA 正規宣告陣列的方式與 C 語言完全不同,但後來也有加入一些宣告語法是仿 C 語言的。

2.1 一維陣列變數宣告

◉ 格式1:dataType[] arrayRefVar; (首選)

int[] a;
String[] str;

◉ 格式2:dataType arrayRefVar[]; (一樣可以作用,但非首選)

int a[];
String str[];