2021年6月23日 星期三

JAVA 物件導向的概念-04 建構子,產生物件時直接給變數值

   這邊直接拿前面寫過的程式來改, 在類別裡面設好建構子後,主程式裡可以直接在產生物件時直接給變數值,同時,如果這些變數之後不會更動,則類別裡面也可以不設定這些變數的 setter 。

類別程式碼如下:

// 編寫人:Lancelot Cheng
public class Person {
// 這個類別是人類共有屬性的集合,理想上是人都會有的屬性,不過我這邊把它當成遊戲人物。

// 字串名字
private String name;
// 整數年齡
private int age;

// 字串稱號,宇串武器,整數力量,整數傷害
private String title, weapon;
private int power, hurt;

// 以下是建構子。
public Person( String n, int a, String t, String w, int p) {
name = n;
age = a;
title = t;
weapon = w;
power = p;
}



static String king = "亞瑟";
// static 在記憶體上是唯一的位置,當類別被使用到時就產生了,不用到 new 出物件才產生。
// 也就是說 king 是 person 物件與其子類的物件所共享的變數。

static public final String species = "人類";
// 此變數是 static final ,即代表它是所有 person 物件及其子物件所共享的常數,即唯一且不能修改。

// 以下方法用來顯示物件的資料。
void showFile() { // 靜態方法。
System.out.println( "名:" + name +",年紀:" + age + ",稱號:" +
title + ",力量:" + power +",種族:"+ species + ",效忠:" + king);
}

// 以下方法是物件的傷害能力。
void attack() { // 靜態方法。
System.out.println("使用" + weapon);
hurt = power*power;
System.out.println("給予敵人傷害" + hurt);
}

public static String getKing() {
return king;
}

public static void setKing(String king) {
Person.king = king;
}


}

主程式碼如下:

// 編寫人:Lancelot Cheng
public class PersonInformation {

public static void main(String[] args) {

Person lancelot = new Person("藍斯洛特", 18, "湖上騎士", "樹枝", 1000);
Person guinevere = new Person( "桂妮薇兒", 17, "人間的海倫", "梅玫刺劍", 800);

lancelot.showFile();
lancelot.attack();

System.out.println();

guinevere.showFile();
guinevere.attack();

System.out.println();

Person.setKing("自己"); // 靜態變數也稱類別變數,故可以直接用類別名稱操作。
System.out.println("在 Person.setKing 更改後。");
lancelot.showFile(); // 兩個人效忠的對像會一起改變,理由見 Person 類別內變數 king 的註解。
guinevere.showFile();

}
}

執行結果:


名:藍斯洛特,年紀:18,稱號:湖上騎士,力量:1000,種族:人類,效忠:亞瑟 使用樹枝 給予敵人傷害1000000 名:桂妮薇兒,年紀:17,稱號:人間的海倫,力量:800,種族:人類,效忠:亞瑟 使用梅玫刺劍 給予敵人傷害640000 在 Person.setKing 更改後。 名:藍斯洛特,年紀:18,稱號:湖上騎士,力量:1000,種族:人類,效忠:自己 名:桂妮薇兒,年紀:17,稱號:人間的海倫,力量:800,種族:人類,效忠:自己 Process finished with exit code 0




JAVA 物件導向的概念-03 物件中有物件的探索

   這一篇我試著讓物件中有其他物件,或是使用物件的方法產生另一個物件。以下是類別 A 和類別 B 的程式碼。結果是可行的,可見 JAVA 在編寫上有一定的自由度。

類別 B 只是單純的類別,

// 編寫人:Lancelot Cheng
public class B {
int b1 = 10000;
public double b2() {
return 1.0;
}

public int getB1() {
return b1;
}

public void setB1(int b1) {
this.b1 = b1;
}

}

類別 A 中有定義 a4 為 B 物件,a2 方去中也有定義 a3 為 B 的物件。

// 編寫人:Lancelot Cheng
public class A {
int a1 = 1;

B a4 = new B();

public double a2() {
B a3 = new B();
System.out.println(a3.getB1());
return 1.0;
}

public int getA1() {
return a1;
}

public void setA1(int a1) {
this.a1 = a1;
}

public B getA4() {
return a4;
}

public void setA4(B a4) {
this.a4 = a4;
}
}

再來是主程式,定義 m1 為 A 物件,使用 m1.a2 方法,得到了為 B 物件的 a3 之 b1 值。也可以用 m1.getA4() 方法得到為 B 物件的 a4 之位址。

// 編寫人:Lancelot Cheng
public class Main {

public static void main(String[] args) {
System.out.println("Main");

A m1 = new A();
System.out.println(m1.getA1());
m1.a2();
System.out.println(m1.getA4());
}
}

以下是結果。

Main
1
10000
B@7f63425a

Process finished with exit code 0

上述是 A 物件擁有 B 物件的寫法,程式上可以跑。
然而,如果你的程式是 A 、 B 物件互相擁有對方,程式就會出錯了,
無窮的配置記憶體過給新物件,直到不夠。
另外我又試了 A 物件擁有 A 物件的寫法,一樣可行。只是記憶體也是會被配置到不夠。
JAVA 允許這種寫法,只是不知道有沒有用到的機會。當然用時要設好條件,
不然記憶體也是會被配置到不夠。
(從後來我做的結合關係範例看來,只宣告不實作的情況下,可以避免記憶體一直配置給新物件的問題。)
(觀念變好後,回來看這一篇,發現用詞不精確,有空再來修改。)




JAVA 物件導向的概念-02 兩個物件的競爭(純練習)

   這一篇沒有要講述什麼概念,只是一個小小的練習。想像兩個玩家在玩翹翹板,他們的起始條件相同,有相同的質量,待在等距離長的力臂兩端。為了獲得勝利,一邊採取增加質量的方式,另一邊採取增加力臂的方式。

玩家的類別
// 編寫人:Lancelot Cheng
public class Player {
// 玩家
int mass,arm,tau;

void showParameter(){
System.out.println("質量:" + mass +" 力臂:" + arm);
}

void moment(){ // 計算力矩
tau = mass * 10 * arm; // 這邊為了讓其值都是整數,重力加速度設為 10 公尺每秒平方。
}

public int getTau() {
return tau;
}

public void setTau(int tau) {
this.tau = tau;
}

public int getMass() {
return mass;
}

public void setMass(int mass) {
this.mass = mass;
}

public int getArm() {
return arm;
}

public void setArm(int arm) {
this.arm = arm;
}
}

主程式
// 編寫人:Lancelot Cheng
public class Main {

public static void main(String[] args) {
System.out.println("兩個物件的翹翹板競爭");

// 似用類別 Player 產生兩個玩家,並給定相同的初值。
Player pM = new Player();
pM.setArm(1);
pM.setMass(4);
pM.showParameter();
pM.moment();
System.out.println(pM.getTau());

Player pA = new Player();
pA.setArm(1);
pA.setMass(4);
pA.showParameter();
pA.moment();
System.out.println(pA.getTau());

for (int i=1; i<=100; i++){
pM.moment();
pA.moment();
if( pM.getTau() <= pA.getTau() ){
pM.setMass(pM.getMass()+1); // pM 玩家透過增加質量來取得優勢。
}
else{
pA.setArm(pA.getArm()+1); // pA 玩家透過增加力臂來取得優劫。
}
System.out.println( i + " pM 的 M 與 A:" + pM.getMass() + ";" + pM.getArm()
+ " pA 的 M 與 A:" + pA.getMass() + ";" + pA.getArm());
}
}

}

兩邊值增加的過程,結果

兩個物件的翹翹板競爭
質量:4 力臂:1
40
質量:4 力臂:1
40
1  pM 的 M 與 A:5;1  pA 的 M 與 A:4;1
2  pM 的 M 與 A:5;1  pA 的 M 與 A:4;2
3  pM 的 M 與 A:6;1  pA 的 M 與 A:4;2

中間略~~ 97 pM 的 M 與 A:81;1 pA 的 M 與 A:4;21 98 pM 的 M 與 A:82;1 pA 的 M 與 A:4;21 99 pM 的 M 與 A:83;1 pA 的 M 與 A:4;21 100 pM 的 M 與 A:84;1 pA 的 M 與 A:4;21 Process finished with exit code 0

  我個人不覺得這是一次成功的練習,因為我是用主程式來調整兩個玩家物件的參數,比較輸贏,而非再設一個物件去做這件事,不過我認為做得到。我好奇的是,能否寫成讓這兩個玩家物件主動去探查對方的力矩值,然後調整自身的參數?下次再試看看。(後來我做了結合關係的範例練習,我判斷完全辦得到!)

JAVA 物件導向的概念-01 用類別創造物件,是為了偷懶

   假設我要在程式中鍵入藍斯洛特的資料,我會建立幾個屬性,例如名字、身高、體重、生日,那麼建立完了以後,如果我又要再建立桂妮薇兒的資料時,又得再建立名字、身高、體重、生日一次。那是多麼麻煩啊!

  在 JAVA 中,我們不會這麼做,而是先建造一個人的類別,我們就稱它為人類別好了,在這個類別裡面我們建好了人所擁有的屬性,再用人類別創造藍斯洛特和桂妮薇兒的物件,一創造出來,他們就擁有人的屬性了。同樣的,我們可以用人類別創造其他的人物件,他們也都會擁有人的屬性,這方便多了。

  基於上段的說明,人類別內所建的屬性最好是所有人都會有的共通屬性,例如只要是人就一定有名字、性別、生日等。以下是類別和主程式的程式碼,記得都要創建在該 project 的 src 資料裡面。

類別的程式
// 編寫人:Lancelot Cheng
public class Person {
// 這個類別是人類共有屬性的集合,理想上是人都會有的屬性,不過我這邊把它當成遊戲人物。

// 字串名字
String name;
// 整數年齡
int age;

// 字串稱號,宇串武器,整數力量,整數傷害
String title, weapon;
int power, hurt;

static String king = "亞瑟";
// static 在記憶體上是唯一的位置,當類別被使用到時就產生了,不用到 new 出物件才產生。
// 也就是說 king 是 person 物件與其子類的物件所共享的變數。

static public final String species = "人類";
// 此變數是 static final ,即代表它是所有 person 物件及其子物件所共享的常數,即唯一且不能修改。

// 以下方法用來顯示物件的資料。
void showFile() { // 靜態方法。
System.out.println( "名:" + name +",年紀:" + age + ",稱號:" +
title + ",力量:" + power +",種族:"+ species + ",效忠:" + king);
}

// 以下方法是物件的傷害能力。
void attack() { // 靜態方法。
System.out.println("使用" + weapon);
hurt = power*power;
System.out.println("給予敵人傷害" + hurt);
}

// 以下是按滑鼠右鍵,然後點 Generate,再選 Getter and setter 產生的。
// 只要前面的變數有設好,它會顯示選項,讓你選擇哪些變數要有 Getter 和 Setter。
// 有設定 Getter and setter 的變數才能在主程中得到與設定其值。


public static String getKing() {
return king;
}

public static void setKing(String king) {
Person.king = king;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getWeapon() {
return weapon;
}

public void setWeapon(String weapon) {
this.weapon = weapon;
}

public int getPower() {
return power;
}

public void setPower(int power) {
this.power = power;
}

public static String getSpecies() {
return species;
}
}
忘了說明封裝,利用類別產生出來的物件,裡面的有哪些屬性,屬性又為何,我們不得而知,此特性稱為封裝,方式就在那些變數前加上 private ,如果想要得到其值或是設定其值,就必須設定 getter and setter 。你可能會覺得很奇怪,你都看得到程式碼,如何會不知道其屬性呢?依情況的不同,你可能會需要和別人合作,而相互之間都想保留自己程式碼中的機密資訊,對方給你的可能是執行檔案,而非程式碼,你所能得到與設定的值就只有對方有設定 getter and setter 的變數。

Elton 補充說明:封裝就是不希望任何人可以透過任意語法來存取物件中的資料,而我們只統一對外公開2個出入口:getter、setter。任何人只能用上面的getter/setter來存取物件中的數據,進而統一存取規範、亦達到資料保護。

主程式
// 編寫人:Lancelot Cheng
public class PersonInformation {

public static void main(String[] args) {

Person lancelot = new Person(); // 創造名為 lancelot 的 person 物件
lancelot.setName("藍斯洛特"); //
lancelot.setAge(18);
lancelot.setTitle("湖上騎士");
lancelot.setWeapon("樹枝");
lancelot.setPower(1000);

lancelot.showFile();
lancelot.attack();

System.out.println();

Person guinevere = new Person(); // 創造名為 guinevere 的 person 物件
guinevere.setName("桂妮薇爾");
guinevere.setAge(17);
guinevere.setTitle("人間的海倫"); // 她好像沒有稱號,我亂編的。
guinevere.setWeapon("玫瑰刺劍");
guinevere.setPower(800);

guinevere.showFile();
guinevere.attack();

System.out.println();

Person.setKing("愛情"); // 靜態變數也稱類別變數,故可以直接用類別名稱操作。
        System.out.println("在 Person.setKing 更改後。");
lancelot.showFile(); // 兩個人效忠的對像會一起改變,理由見 Person 類別內變數 king 的註解。
guinevere.showFile();
}
}

執行結果

名:藍斯洛特,年紀:18,稱號:湖上騎士,力量:1000,種族:人類,效忠:亞瑟
使用樹枝
給予敵人傷害1000000

名:桂妮薇爾,年紀:17,稱號:人間的海倫,力量:800,種族:人類,效忠:亞瑟
使用玫瑰刺劍
給予敵人傷害640000

在 guinevere.setKing 更改後。
名:藍斯洛特,年紀:18,稱號:湖上騎士,力量:1000,種族:人類,效忠:愛情
名:桂妮薇爾,年紀:17,稱號:人間的海倫,力量:800,種族:人類,效忠:愛情

Process finished with exit code 0

JAVA 字串的方法

   在我買的書中還有寫上其他字串或字元的方法,依我以前寫程式的經驗,需要時再來查就好了,所以只練習了以下方法。短短幾天看完了半本 JAVA 學習手冊,主要是因為我學過其他的程式語言。接下來是 JAVA 的超級重點——物件導向。期待之!

/* 字串相關指令 */
public class ArrayandString {
public static void main(String[] args) {
// 建構字串的方式

System.out.println("建構字串");
String str1 = "我愛一條條柴一二三";
String str2 = new String("who cares?");
String str3 = new String(); // 空字串
char[] ch1={'誰','獨','尊'};
String str4 = new String(ch1); // 將字元陣列變成字串,二維的字元陣列無法使用此指令。
byte[] by1={1,2,3};
String str5 = new String(by1); // 將位元組陣列變成字串,沒弄懂,我猜沒有很重要,先放著。
System.out.println("輸出上面已經宣告的字串");
System.out.println(str1 + "," + str2 + "," + str3 + "," + str4 + "," + str5);
System.out.println("注意到,,之間沒有字是因為空字串。");
System.out.println();

System.out.println("str1 的長度=" + str1.length()); // 從這一行可以知道,每個被宣告成字串的物件,也都擁有這個方法。
// 在這邊先知道如何用就好,後面物件導向時會說明概念。
System.out.println("str2 =" + str2);
String str6 = str2.toUpperCase(); // 將所有字母變大寫,指定給 str6 。
System.out.println("str6 =" + str6);
String str7 = str6.toLowerCase(); // 將所有字母變小寫,指定給 str7 。
System.out.println("str7 =" + str7);

System.out.println();
System.out.println("以下是找索引的指令");
System.out.println(str1.indexOf('一'));
// 從頭正向找出字串 str1 中的字元 '一' 的索引。
System.out.println(str1.lastIndexOf('一'));
// 從尾反向找出字串 str1 中的字元 '一' 的索引。
System.out.println(str1.indexOf('一', 1));
// 從索引 1 開始正向找出字串 str1 中的字元 '一' 的索引。
System.out.println(str1.lastIndexOf('一', 3));
// 從索引 3 開始反向找出字串 str1 中的字元 '一' 的索引。

System.out.println(str1.indexOf("條柴"));
// 從頭正向找出字串 str1 中的字串 "條柴" 的索引。
System.out.println(str1.lastIndexOf("條柴"));
// 從尾反向找出字串 str1 中的字串 "條柴" 的索引。
System.out.println(str1.indexOf("條柴", 1));
// 從索引 1 開始正向找出字串 str1 中的字串 "條柴" 的索引。
System.out.println(str1.lastIndexOf("條柴", 3));
// 從索引 3 開始反向找出字串 str1 中的字串 "條柴" 的索引。

// 注意到上面兩組所使用的方法名稱是相同的,
// 但依輸入的是字元或字串,而使用其相對應的方法,這個叫做多載。


// 其他宣告方式測試
int [] a = { 0, 1, 2, 3};
int [][] b = {{0,1},
{2,3}};
char[][] c = {{'我','命'},
{'好','苦'}};
String [][] d = {{"武林至尊,","寶刀屠龍!"},
{"倚天不出,","誰與爭鋒?"}};
}
}

以下是結果
"C:\Program Files\Java\jdk-11\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.2.4\lib\idea_rt.jar=62566:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\ArrayandString\out\production\ArrayandString ArrayandString
建構字串
輸出上面已經宣告的字串
我愛一條條柴一二三,who cares?,,誰獨尊,
注意到,,之間沒有字是因為空字串。

str1 的長度=9
str2 =who cares?
str6 =WHO CARES?
str7 =who cares?

以下是找索引的指令
2
6
2
2
4
4
4
-1

Process finished with exit code 0

對大眾而言,人工智慧似乎離他們很遠

    在我學過程式後,我懷疑人工智慧有實現的一天,電腦就是按照指令行動的笨蛋而已,最大的優點就是不會累,可以快速的重複相同的工作。然而在我研究果蠅的大腦的過程中,我開始相信人工智慧是可能的,神經元只是一個能夠激發與被激發的細胞,數以千億的神經元相互連接,形成了我們有意識的大腦,相同的原理下,電腦有機會也擁有意識,我心中開始了有一些藍圖。有一天在圖書館亂逛時,看到了一本類神經演算法的書,裡面提到方式和我心中的藍圖挺相近的,當然也更好,一個人的獨想是很難超越那些專家的研究的。那時候我就預言人工智慧有一天一定會成功。幾年後,阿法狗打敗了李世乭,深深的振撼了我!沒想到那麼快!阿法狗用的技術叫深度學習,實際上就是類神經演算法。

  相較於我對人工智慧的震驚,家人、同學、朋友似乎都不覺得那有什麼重要性。在一場演講練習中,我選則了人工智慧為主題,如果讓聽的人感到震驚,就算我成功,但結果是失敗了!

  一個年長的女人似乎憤憤不平的對我說:如果都給人工智慧取代,那人要做什麼?人工智慧再怎樣也是人寫的,它不可能超越人類。

  一個臉書上的友人對我出言不遜:不要把人工智慧當神!

  在我的立場,我只在乎人工智慧能辦到什麼,我並不在乎人會不會被取代,雖然我認為一定會。在很多領域中人工智慧已經超越人類,但目前只用來協助人類。我並沒有把人工智慧當神,同時我也沒有把人類當神,一個不是神的機器超越了不是神的物種,有什麼好奇怪的嗎?

  無論對人工智慧有多少敵意或不信任,人工智慧仍不斷的發展中,會把這些質疑的人與沒感覺的人抛得遠遠的。

  其實我很想學人工智慧,不過現階段大概是沒有機會吧!先學 JAVA 吧!希望五年內,人工智慧不會變得比我還會寫 JAVA。

~藍斯洛特~

JAVA 方法的使用-04 傳值或傳址的測試

   在方法的使用-01 已經有提到了,這邊特別再寫一次,基本上是比較進入方法前後(方法內對變數做更動),其值不變的就是傳值,其值改變的就是傳址,這是因為傳址的參數是讓電腦依位置更動其內容,所以改到的是同一個變數。而傳值的參數是方法有設變數接收其值,所以之後在方法內做的更動並不會動到原本的變數。

  不過,對於字串並不是這麼一回事,字串一旦宣告了就不能改變其值,後來所做的更改是令新的位址存新的值指定給原本的變數,而舊的值仍在原本的位址,沒有被取代。在傳給方法時,發生了什麼事,在以下範例的註解有說明。

/* 傳址或傳值的測試 */

public class AorV {

public static void funA(int aa, double bb, char cc, String dd, int ee[]) {
System.out.println("  已進入方法 A 中!");
System.out.println("    改值前" + aa + "," + bb + "," + cc + "," + dd + "," + ee[0]);
aa*=100;
bb*=100;
cc= '哭';
dd= "你恨我!";
ee[0] = 0;
System.out.println("    改值後" + aa + "," + bb + "," + cc + "," + dd + "," + ee[0]);
System.out.println("  方法 A 結束!");
}

public static void main(String[] args) {
int a = 1;
double b = 3.1415926;
char c = '笑';
String d = "我愛你";
int e[] = {1024, 2048};

System.out.println("主程式" + a + "," + b + "," + c + "," + d + "," + e[0]);
funA( a, b, c, d, e);
System.out.println("主程式" + a + "," + b + "," + c + "," + d + "," + e[0]);
// 進入方法的前後,a、b、c 值沒有變,屬於傳值,
// 那 d 也沒有變啊!為什麼不屬於傳值?實際上字串一旦宣告完成就不能再改變所屬位址的值,
// 在方法中給 dd 指定了舊的位址,然後指定新的值時,
// 其實只是新的位址內存了新的值並指定給 dd ,原本的值仍在,沒有被取代。
// e 的值變了,屬於傳址,雖然看起來是只有傳 e[1] ,但其實是傳址過去,
// 所以方法那邊不只可以用 e[1],也可用 e[0]。

}
}

結果
主程式1,3.1415926,笑,我愛你,2048
  已進入方法 A 中!
    改值前1,3.1415926,笑,我愛你,1024
    改值後100,314.15926,哭,你恨我!,0
  方法 A 結束!
主程式1,3.1415926,笑,我愛你,2048

Process finished with exit code 0

JAVA 陣列的使用

  這部份真得說 fortran 使用起來方便多了,JAVA 中的陣列也是必須實作出來的物件,寫法也比較讓人眼睛痛。也沒有矩陣相乘的指令,必須自己寫才行。

/* 陣列 */
// 雖然取名為 Matrix,但這裡其實只是想測試陣列,之所以不取名為 Arrays 是怕犯了跟上次一樣取名的錯誤。
// 身為物理人,其實應該至少寫個矩陣相乘的例子,希望以後有機會補上。
// 對於像我這種沒學過 JAVA 但學過其他程式語言的人來說,JAVA 在宣告陣列似乎很麻煩,
// 這是因為 JAVA 的陣列是物件,必須把它實作出來。

public class Matrix {
public static void main(String[] arge) {
System.out.println("宣告一維整數陣列");
int [] matrixA = new int[4];
for (int i = 0; i<= 3; i=i+1) {
matrixA[i] = i;
System.out.println(matrixA[i]);
}
System.out.println("宣告一維實數陣列");
double [] matrixB = new double[4];
for (int i = 0; i<= 3; i=i+1) {
matrixB[i] = i + 0.5;
System.out.println(matrixB[i]);
}
System.out.println("宣告一維字串陣列");
String [] matrixC = new String[4];
for (int i = 0; i<= 3; i=i+1) {
matrixC[i] = "我是藍斯洛!";
System.out.println(matrixC[i]);
}

System.out.println("宣告二維整數陣列");
int [][] matrixD = new int[2][2];
for (int i = 0; i <= 1; i++) {
for ( int j =0; j <= 1; j++) {
matrixD[i][j] = i*10 + j;
System.out.println(matrixD[i][j]);
}
}

System.out.println("宣告三維整數陣列");
int [][][] matrixE = new int[3][3][3];
for (int i = 0; i <= 2; i++) {
for (int j =0; j <= 2; j++) {
for (int k = 0; k <= 2; k++ ) {
matrixE[i][j][k] = i * 100 + j * 10 + k;
System.out.println(matrixE[i][j][k]);
}
}
}
}
}

JAVA 一些數學指令的使用 2

 /* 一些數學指令 */

// 在這邊不需要引入,只是每個指令前都有 Math. ,另外打完時,要選擇適合的型別,不過我都選 double 。
public class Math2 {
public static void main(String[] args) {
System.out.println(Math.abs(-1000));
System.out.println(Math.min(-3.14159, -2.71828));
System.out.println(Math.max(-3.14159, -2.71828));
System.out.println(Math.random());
System.out.println(Math.round(4.63));

System.out.println("自然數 e:" + Math.E);
System.out.println("圓周率 pi:" + Math.PI);
System.out.println("自然數 e 的二次方:" + Math.exp(2));
System.out.println("找出大於或等於 pi 的整數:" + Math.ceil( Math.PI));
System.out.println("找出最接近 pi 的整數:" + Math.rint( Math.PI));
System.out.println(" 2 的 10 次方:" + Math.pow(2,10));
System.out.println("將弳度轉角度,例如 PI ->" + Math.toDegrees(Math.PI));
System.out.println("將角度轉弳度,例如 180 -> =" + Math.toRadians(180));

}
}

學習 JAVA 的心得-01 如何學習基本的語法

   程式設計在中國好像叫作編程,意思是編製程序。我認為是個很好名字,從名字知道其內含。所做的事,就是安排流程給電腦,電腦按照順序執行指令,完成人們想要的工作。這其實和益智遊戲很像,而且沒有惟一的答案。這是我覺得寫程式的好玩之處。那要如何玩得好這個益智遊戲呢?我的答案有三個:熟悉指令、理解問題、多知道一些演算法。

  該如何熟悉指令?坊間很多書都會提供指令上的說明,與相關範例,照著做就好了嗎?我並不這認為。照著打一遍,之後修改參數,看看會有什麼變化,探索指令的極限,會讓你更快瞭解指令能夠使用的自由程度。例如同樣是迴圈,在 fortran 和 JAVA 中就有不同的特性。

do i = 1, 10, 2

    i=i+1

enddo

上面是 fortran 的迴圈程式,在迴圈裡面更改 i 的值是不被允許的,在編譯時就會出錯了。

for ( i = 1; i <= 10; i = i + 2) {

    i = i +1;

}

而上面是 JAVA 的迴圈程式,迴圈裡面允許更改 i 的值。

  就迴圈來看, JAVA 比 fortran 更自由,這意味著某些情況程式可以寫得更精簡,也可以有更多變化,但反過來也可以能因此出錯,各有利弊。另一個熟悉語法的方式就是使用它。

  熟悉基本語法後,已經可以做很多簡單的分析了,但不要以此為滿,因為後面還有更重要的概念要學習,那就是物件導向。再之後要學習套件的使用,到這個地步時,才能真正享受 JAVA 的優勢。

JAVA 一些數學指令的使用

 感覺有一些麻煩,每個指令的使用都要引入~~

另一篇不用,只要每個指令前面都加上 Math. 即可,
但在這邊卻不行,因為我檔名已經叫 Math 了,我犯了取名的錯誤。


/* 一些數學式的使用 */

import static java.lang.Math.abs; // 引入以使用 abs
import static java.lang.Double.min; // 引入以使用 min
import static java.lang.Math.random; // 引入以使用 random

public class Math {
public static void main(String[] args) {

System.out.println("絕對值");
double a=-1234.5678;
int b = -1122333333;
float c = -34;
long d = -922337203;
System.out.println(abs(a));
System.out.println(abs(b));
System.out.println(abs(c));
System.out.println(d);

System.out.println("取兩數中的小數");
System.out.println(min (1,-2));
System.out.println(min(3.14159, 2.71828));

System.out.println("取亂數");
System.out.println(random());

}

} 

JAVA 方法的使用03 方法間的呼叫

 非教學,不會詳細解說。

結論,方法可以相互呼叫,也可以呼叫自己。

 /* 方法呼叫方法測式 */

// 測試結果,方法可以呼叫方法,相互呼叫,呼叫自己,記得要設條件,不然程式跑不完。
public class ClassMethods3 {

static void funA(int i) {
System.out.println("現在在方法 A 中,呼叫方法 B 。");
i++;
funB(i);
}

static void funB(int i) {
System.out.println("現在在方法 B 中,判斷是否呼叫方法 A 。");
if ( i<3 ) {
System.out.println("呼叫方法 A 。");
funA(i);
}
else {
System.out.println("不呼叫,方法呼叫結束。");
}
}

static void funC(int i) {
System.out.println("現在在方法 C 中,判斷是否呼叫自己 。");
i++;
if ( i<3 ) {
System.out.println("呼叫方法自己。");
funA(i);
}
else {
System.out.println("不呼叫,方法呼叫結束。");
}
}

JAVA 方法的使用-02 大家都能用的變數

 非教學,但如果你懂 JAVA 程式的基本結構,或已經學過其他程式,也許以下對你有用。

static 修飾變數的位置是在類別,而非方法或主程式之內,這符合一般常理,因為它所修飾的變數是全域變數。

 /* 變數的使用範圍 */

// 傳入方法中的變數與方法中定義的變數都只能在方法中改變其值,其他程式改變不了,
// 所以方法中的變數名稱可以和主程中的變數名稱相同,它們各有自己的位址。
// 在類別中用 static 修飾的變數則不管主程式或方法都能改變,
// 因為在主程式中與方法中的更改,都是動到同一個變數。以下只測試 static 修飾子。


public class ClassMethods2 {
// 類別變數宣告。
static int a = 1;
// 使用修飾子 static 時,表示變數就屬於類別本身,稱為類別變數,差不多可以等於其他程式中的全域變數。

// 類別方法
static void func() {
a = 2;
// 因為是類別變數,在函數中或是主程式中可以直接使用,不需要再次宣告,或是另設變數接收其值。
}

public static void main(String[] args) {
a = 1000;
System.out.println( a );
func();
System.out.println( a );
// 當然,無論在函數中或主程式中更改類別變數,都是改到同一個變數,所以執行函數前後,其值不同。
}
}