C50108
Search…
職訓局里程碑
2019/0509/Java物件導向(函式)_儲存型態+回傳值+多載+自制+例外處理+this參照+存取+複合
https://matthung0807.blogspot.com/2018/02/java-overload.html

函式存取方式 三種 公開public 私有private 保護protected

表示這個函式 為 靜態方法/類別函式
如果有這個宣告在編譯時就會佔有記憶體
不用透過關鍵字即可已被值接呼叫

一般(非類別)沒宣告為static靜態的 就必須透過建構式 new 配置
因為一般的則為動態的配置記憶體方式
然後以物件名稱.函式方法名稱(引述列)來呼叫
類別函式可以直接用函式名稱(引述列)來呼叫,或已類別名稱.函式方法名稱(引述列)來呼叫

以前沒有物件導向時就有了
函式型別
函式傳回 (return)值的資料型別
Ex void or int string …
函式沒有回傳值則型別為void 沒有回傳值
在函式內看不到return的關鍵字使用
權限 記憶體配置方式 函式名稱 參數列 參數名稱
Public static void main (string str)

函式名稱(參數, 參數…)
變數 = 函式名稱(參數, 參數…)

傳值(pass by value
拷貝一份傳給對應參數
在函式執行過程永遠參照拷貝的那份最原本的
傳參照(pass by reference
起始參數位址傳遞給參數
如果在函式執行過程改變了那參數也會被改變

印a陣列 印出 在另一個函數改變a
Math.sqrt ( 靜態方法可以直接呼叫
Class 一系列數學特定功能 ( 開根號等等 sqrt是裡面其中一種開根號方法
有點懶得打程式碼…

居然可以讓
Mether跟原本庫的掛件靜態類別方法同名稱???只差在namespace不一樣
Public static void print (int x[]){System.out.print(x[i]+””)};
package com.example.java;
public class Java12_9 {
public static void main(String[] args) {
// TODO 自動產生的方法 Stub.
int a[] = { 2, 4, 9, 16, 25, 36, 49, 64, 81 };
print(a);
sqrt(a);
print(a);
}
public static void print(int x[]) {
System.out.print("陣列內容為:");
for (int i = 0; i < x.length; i++)
System.out.print(x[i] + " ");
System.out.println();
}
public static void sqrt(int x[]) {
for (int i = 0; i < x.length; i++)
x[i] = (int) Math.sqrt((double) x[i]);
}
}

一樣有點懶得打程式碼…
宣告一靜態函數 ( 對於char 變數來說是內部
裡面
宣告陣列int
宣告char
印出
宣告一靜態函數 (對於剛剛的char變數來說是外部
去改剛剛 宣告的 基礎型態char的值
印出 (外部被更動char不會被改變??

主要是要說
先宣告一個印出函數
一個函數有return一個沒有但藉由參數reference達到與return相同效果
順道講矩陣相加
矩陣運算 - Google Search
Google
範例java12_10.java裡面有以下範例

使用同一個方法(函式)名稱
具備多種相似的功能
設計加法函式,讓它可以處理整數的相加,浮點數的相加,字串的相加,都是用add()這個函數的功能,只差在型態不一樣。
記得不同多載還要指定函式回傳值型態
( 然後要考慮value或reference (有點像是區域變數的概念???回傳值 沒回傳值
add(int x , inty)
string add(string x , string y)
char add(char x , char y)

package com.example.java;
public class Java12_10 {
public static void main(String[] args) {
// TODO 自動產生的方法 Stub.
int a[][] = { { 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 } };
int b[][] = { { 0, 1, 2, 3, 0 },
{ 2, 1, 3, 3, 5 } };
int c[][] = new int[a.length][a[1].length];
// char d= 'c';
// print('a', a);
// print('b', b);
// c = add(a, b);
// add(a,b,c);
// print(d, c);
// System.out.println("d ="+d);
int d=5,e=6,f=0;
System.out.println("f ="+f);
f=add(d,e);
System.out.println("f ="+f);
}
public static void print(char c, int x[][]) {
System.out.println(c + "陣列內容為:");
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++)
System.out.printf("%2d ", x[i][j]);
System.out.println();
}
System.out.println();
c = 'k';
System.out.println("內部字元變數 c:"+c);
}
public static int[][] add(int x[][], int y[][]) {
int z[][] = new int[x.length][x[1].length];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++)
z[i][j] = x[i][j] + y[i][j];
}
return z;
}
public static void add(int x[][], int y[][], int z[][]) {
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++)
z[i][j] = x[i][j] + y[i][j];
}
}
public static int add(int x,int y)
{
int z = x + y;
return z;
}
public static String add(String x , String y) {
String z = new String();
z = x.concat(y);
return z;
}
}

宣告一個無回傳值靜態函數,參數為字串陣列
並在裡面宣告值

package com.example.java;
public class Java12_11 {
public static void main(String[] args) {
// TODO 自動產生的方法 Stub.
int i = 1, j = 2, k = 0;
String s1 = "I love ";
String s2 = "Java!";
String s3 = new String();
k = add(i, j);
s3 = add(s1, s2);
System.out.println("i=" + i + ", j=" + j + ", k=i+j=" + k);
System.out.println("s1=\"" + s1 + "\", s2=\"" + s2 + "\", " + "s3=s1+s2=\"" + s3 + "\"");
}
public static int add(int i, int j) {
return (i + j);
}
public static String add(String i, String j) {
return (i + j);
}
}

設計Time1類別會表示一日中的時刻
Private int 具有實體變數 hour minute second
用來表示時間格式
24小時制 hours 0-23 minutes seconds 0-59
Time1類別包含public方法setTime、toUniversalString、toString
這些方法也稱為類別,
提供給使用者public服務
public service或public介面( public interface (之後會在講

Private int hour; // 0-23
Private int minute; // 0-59
.
.
.
.
.

設計時若沒有軒告建構子,編譯器會提供預設版本建構子
每個int實體變數都會得到預設值0
也可以在建構的時候輸入
然後方式跟指定區域變數方式相同

Ex 輸入時間範圍錯誤
方法setTime是一個public方法
宣告三個int參數用來設定時間
型態或範圍出錯時就出現例外處理訊息
可以利用 try catch 捕捉例外狀況 避免利用錯誤資料計算發生錯誤

Throw敘述 會建立 一個 IllegalArgumentException物件
Throw跟new好像都是敘述 ? 結果查完後好像也是靜態類別之一 是關鍵字
C# Keywords
docsmsft
就是一種語法的keyword

package com.example.java;
public class Time1 {
private int hour; // 0 - 23
private int minute; // 0 - 59
private int second; // 0 - 59
public void setTime(int hour, int minute, int second) {
if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60) {
throw new IllegalArgumentException("輸入的 \"小時、分鐘、秒\" 超過範圍限制,發生位置(setTime.12)");
}
this.hour = hour;
this.minute = minute;
this.second = second;
}
public String toUniversalString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public String toString() {
return String.format("%d:%02d:%02d %s", ((hour == 0 || hour == 12) ? 12 : hour % 12), minute, second,
(hour < 12 ? "AM" : "PM"));
}
}

接著 new一個剛剛新增自制類別作測試
補圖

package com.example.java;
public class Time1Test {
public static void main(String[] args) {
// TODO 自動產生的方法 Stub.
Time1 t1 = new Time1();
displayTime("已建立新類別 Time1",t1);
t1.setTime(11, 23, 54);
System.out.println(t1.toUniversalString());
try {
t1.setTime(20, 23, 54);
displayTime("已設定完成時間",t1);
}catch (Exception ex){
System.out.println("錯誤發生 : "+ex.getMessage());
}
}
private static void displayTime(String header,Time1 t)
{
System.out.printf("%s%n24小時制通用時間:%s%n12小時制時間:%s%n",header,t.toUniversalString(),t.toString());
}
}
除了自己建立類別與物件外
也有內建的J SE8- Date/Time 物件
以下簡介內建類別與物件
在官方文件也有很清楚介紹
Java Platform SE 8
一般在撰寫程式的時候如果標準sdk內有內建的類別與物件就不會在自己去實作

參數private
在除了類別內無法在外面引用與查詢看不到

變成值接指定 = 造成間接錯誤
這個好像會沒有程式碼 老師把他跟上一個寫在一起

關鍵字this
存取指向自己的參照
This reference
如果class沒有寫
編譯器也會自己補進去
同一個java檔案,包含多個類別檔案時會分開類別檔.class
但保護層級的class必須在同一個.class檔案內,不然也是會發生錯誤

一個檔案兩個class
Public class ThisTest {}
Class SimpleTime {}
一個java檔案裡面
只有一個可以被宣告為Public
第二個class在外部無法引用public內的東西
簡單來講 棕色跟藍色是不同東西
雖然都是容器,是變數
棕色是區域變數
藍色是類別變數
不寫也可以 編譯器會自己加上去
House
This.minute
This.second

package com.example.java;
public class ThisTest {
public static void main(String[] args) {
SimpleTime t1 = new SimpleTime(16,20,15);
System.out.println(t1.toUniversalString());
}
}
class SimpleTime {
private int hour; // 0 - 23
private int minute; // 0 - 59
private int second; // 0 - 59
public SimpleTime(int h, int m, int second) {
if (h < 0 || h >= 24 || m < 0 || m >= 60 || second < 0 || second >= 60) {
throw new IllegalArgumentException("輸入的 \"小時、分鐘、秒\" 超過範圍限制,發生位置(setTime.12)");
}
hour = h;
this.minute = m;
this.second = second;
}
public String toUniversalString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public String toString() {
return String.format("%d:%02d:%02d %s", ((hour == 0 || hour == 12) ? 12 : hour % 12), minute, second,
(hour < 12 ? "AM" : "PM"));
}
}

不同的簽名式signature塑造多種建構子
編譯器會將建構子呼叫中引述的數量、型別、順序與建構子宣告所指定的參數數量型別順序比對,呼叫正確的建構子
布林 初始預設值為 flase 參照則為 null
範例有五個 最後一個比較特殊 參數的本身就是他自己這個物件的型態

有些比較細的內容可能要回去看ppt或影片

多載的設定必須利用get與set
宣告說 使用者 如何 輸入參數與多載回傳參數

package com.example.java;
public class Time2 {
private int hour; // 0 - 23
private int minute; // 0 - 59
private int second; // 0 - 59
private int millisecond; // 0 - 999
public Time2() {
this(0, 0, 0, 0);
}
public Time2(int hour) {
this(hour, 0, 0, 0);
}
public Time2(int hour,int minute) {
this(hour, minute, 0, 0);
}
public Time2(int hour,int minute, int second) {
this(hour, minute, second, 0);
}
public Time2(int hour, int minute, int second,int millisecond) {
if (hour < 0 || hour >= 24)
throw new IllegalArgumentException("輸入的 小時 必須在 0-23");
if (minute < 0 || minute >= 60)
throw new IllegalArgumentException("輸入的 分 必須在 0-59");
if (second < 0 || second >= 60)
throw new IllegalArgumentException("輸入的 秒 必須在 0-59");
if (millisecond < 0 || millisecond >= 999)
throw new IllegalArgumentException("輸入的 微秒 必須在 0-999");
this.hour = hour;
this.minute = minute;
this.second = second;
this.millisecond = millisecond;
}
public Time2(Time2 t) {
this(t.getHour(), t.getMinute(), t.getSecond(), t.getMillisecond());
}
public void setHour(int hour) {
if (hour < 0 || hour >= 24)
throw new IllegalArgumentException("輸入的 小時 必須在 0-23");
this.hour = hour;
}
public void setMinute(int minute) {
if (minute < 0 || minute >= 60)
throw new IllegalArgumentException("輸入的 分 必須在 0-59");
this.minute = minute;
}
public void setSecond(int second) {
if (second < 0 || second >= 60)
throw new IllegalArgumentException("輸入的 秒 必須在 0-59");
this.second = second;
}
public void setMillisecond(int millisecond) {
if (millisecond < 0 || millisecond >= 999)
throw new IllegalArgumentException("輸入的 微秒 必須在 0-999");
this.millisecond = millisecond;
}
public int getHour() {
return this.hour;
}
public int getMinute() {
return this.minute;
}
public int getSecond() {
return this.second;
}
public int getMillisecond() {
return this.millisecond;
}
public String toUniversalString() {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
public String toString() {
return String.format("%d:%02d:%02d %s", ((hour == 0 || hour == 12) ? 12 : hour % 12), minute, second,
(hour < 12 ? "AM" : "PM"));
}
}

其實就是
宣告一些變數來放值
New些物件來用
多載些不同參數型態數量的類別或物件
提供些方法讓人用
最後再加上繼承、多型
接著老師在講
物件模組化
低耦合高內聚力
減少行數的
低維護成本
降低錯誤可能性
概念

Set 又稱改變方法 mutator method
Get 又稱讀取方法accessor method
看ptt補
實作get set好像和
把實體變數宣告為public沒啥兩樣
1. 因為宣告為public他會沒辦法驗證參數
2. 具有隱私性 ( 商業邏輯可以藏在裡面
雖然get set 方法提供了存取 private 資料的途徑,但其實還是在現制的方法下
Set方法具有有效性的檢查
但並不會宣告private就自動出現,必須自己實作
內建的
判定方法predicate method
例如 ArrrayList的isEmpty方法

實作try呼叫剛剛做的函數 crath錯誤訊息物件

package com.example.java;
public class Time2Test {
public static void main(String[] args) {
// TODO 自動產生的方法 Stub.
Time2 t1, t2, t3, t4, t5, t6;
t1 = new Time2();
t2 = new Time2(2);
t3 = new Time2(21, 35);
t4 = new Time2(21, 35, 46);
t5 = new Time2(21, 35, 24, 55);
try {
t6 = new Time2(27, 35, 24, 55);
} catch (IllegalArgumentException ex) {
System.out.printf("錯誤發生! 物件初始畫錯誤 : %s %n%n", ex.getMessage());
}
displayTime("t1:時、分、秒、毫秒初始化為預設值 ", t1);
displayTime("t2:指定小時,分、秒、毫秒初始化為預設值 ", t2);
displayTime("t3:指定小時、分,秒、毫秒初始化為預設值 ", t3);
displayTime("t4:指定小時、分、秒,毫秒初始化為預設值 ", t4);
displayTime("t5:指定小時、分、秒、毫秒,初始化", t5);
}
private static void displayTime(String header, Time2 t) {
System.out.printf("%s%n %s%n %s%n", header, t.toUniversalString(), t.toString());
}
}

類別可以包含指向其他類別物件的參照(參數),做為類別成員
擁有關係(has-arelationship

需要紀錄時間所以指向Date物件(生日與雇用時間)
String其實也是類別型態的變數

package com.example.java;
public class Date {
private int month; // 1-12
private int day; // 1-31 based on month
private int year; // any year
private static final int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public Date(int month, int day) {
this(month, day, 2019);
}
public Date(int month, int day, int year) {
if (month <= 0 || month > 12)
throw new IllegalArgumentException("月份錯誤 (" + month + ") 必須在 1-12");
if (day <= 0 || (day > daysPerMonth[month] && !(month == 2 && day == 29)))
throw new IllegalArgumentException("日期錯誤 (" + day + ") 超過指定年、月的正常範圍");
if (month == 2 && day == 29 && !(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
throw new IllegalArgumentException("日期錯誤 (" + day + ") 超過指定年、月的正常範圍");
this.month = month;
this.day = day;
this.year = year;
System.out.printf("Date 物件初始化成功: %s%n", this);
}
public String toString() {
return String.format("%d/%d/%d", month, day, year);
}
}
接著實作

package com.example.java;
public class Employee {
private String firstName;
private String lastName;
private Date birthDate;
private Date hireDate;
public Employee(String firstName, String lastName, Date birthDate, Date hireDate) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDate = birthDate;
this.hireDate = hireDate;
}
public String toString() {
return String.format("%s,%s-雇用日期: %s-出生日期: %s", lastName, firstName, hireDate, birthDate);
}
}

package com.example.java;
public class EmployeeTest {
public static void main(String[] args) {
// TODO 自動產生的方法 Stub
Date birth = new Date(7, 24, 2005);
Date hire = new Date(3, 12, 2016);
Employee employee = new Employee("連杰", "李", birth, hire);
System.out.println(employee);
}
}
剛剛都是動態類別成員

某些其況下特定變數只有一個副本,供類別所有物件共用
此情況下就會使用static欄位 staticfield稱為類別變數class variable
Static變數會用來表示權類別性的資訊
呼叫方式
值接給參照(位址)
或是類別名稱加上.
該類別尚未有物件存在時便已存在執行時期因為編譯的時候就編譯了

多型(Polymorphism)是指父類別可透過子類別衍伸成多種型態,而父類別為子類別的通用型態,再透過子類別可覆寫父類別的方法來達到多型的效果,也就是同樣的方法名稱會有多種行為。

沒手機照片無法拍 看ppt或影片吧
有少東西要看ptt
Copy link
On this page
#前期提要
##函式儲存記憶體型態
##函式傳回值型別
##呼叫函式
#函式呼叫參數狀態有兩種方式
##函式方法多載(method overloading)
##自制類別與物件
##自建構類別與物件的預設值
利用throw 丟出例外處理 IllegalArgument
##題外話 如果不ctrl + f5清空暫存就會造成庫的版本引入錯誤
##this參照
##建構式 不會有回傳型態 都是 void 因為是要給使用者 new的
##存取函式/方法get set
##複合 composition
下次設計自己的class 類別繼承階層
感覺下次就會講多型因為跟繼承有關