好久沒來園子了,春節剛過完,現在面對大家最想說的一句話是:你相親了嗎?
都說:孤獨的男人玩dota,寂寞的女人穿絲襪。 我想現在這個時代屌絲才會天天上QQ、逛校內、跑貓撲、走天涯,沒事發幾句牢騷,
沒事在微博追追某個名人;至於那些高富帥不是駕著法拉利兜風,就是開著保時捷泡妞,亦或者坐在捷豹上在高速路上狂飆。
記得是去年剛開博的時候,說了些關於Delphi的文字,裡面提到了類Pascal語言SCL在工控領域的應用,鑒於目前從事工控的朋友對計算
機感興趣不多,或者說都認為那些關於電腦的內容太難,同時據我所知國內目前還沒有一本關於SCL的教材,於是當時就著手開始編製
一本教程;想著為同行提供一個方便的查閱工具吧,畢竟國內很多的裝置都用到了SCL這個PLC的編程工具,當時在園子裡面也掛了一些文字,現
在提供一個關於這本教材的試讀章節,目前這些文字已經到了第四章了,預計今年7月份能夠完成初稿。
【西門子S7 300 400 SCL編程】下載頁面:http://www.gongkong365.com/bbs/read.php?tid=34524
下載連結:http://www.gongkong365.com/bbs/job.php?action=download&aid=26976
目前這個文檔是DOC格式的,等弄完後,計劃編排成PDF格式的,如果可能的話也許會弄成紙質的吧;這裡就不多說了。
那麼這次我們說點Java的什麼內容呢?
【Java中的構造器】
上一次的文字,說了部分關於OOP的內容,同時在文章中我們設計一個Employ類,這個類具有下面的幾個域:
private String Name; private boolean Gender; private String PhoneNumber; private double Salary;
這裡要說的構造器的作用:構造器的作用就是當系統構造對象的時候,構造器初始化對象。構造器由構造器方法或者構造器函數實現,構造器
方法/函數與類名一致。如下所示:
public employee(String inName,boolean inGender,String inPhoneNumber,double inSalary) { }
這個公有的employee方法就是類employee的構造器(為了方便以後構造器方法和函數均稱構造器)。為了實現構造器初始化執行個體域的目的我們
需要在構造器中添加語句。下面是我們一般的實現:
public employee(String inName,boolean inGender,String inPhoneNumber,double inSalary){ Name=inName; Gender=inGender; PhoneNumber=inPhoneNumber; Salary=inSalary;}
當構造對象的時候,構造器被調用,構造器就將對象的執行個體域初始化為指定的值。例如當我們用下面的語句構造對象時:
new employee("volcanol",true,“13555555555”,1000.0);
新的對象就具有以下的執行個體域值:
Name=“volcanol”
Gender=true;
Phonenumber=“13555555555”;
Salary=1000.0;
構造器與其他的方法和函數不同,構造器需要和new操作符一起使用,通過new操作符申請儲存空間,而通過構造器對對象進行
初始化。
同時不能對已經存在的對象調用其構造器,這樣會導致異常。
構造器要點: 1、 構造器與類同名
2、每個類可以一個以上的構造器
3、構造器可以有0個、1個或者1個以上的參數
4、構造器沒有傳回值,這個比較重要。
5、構造器總是和new操作符一起使用
6、不要再構造器中定義與類執行個體域同名的局部變數。
【顯示參數和隱式參數】
方法用來操作對象以及存取對象的執行個體域。例如方法:
public boolean setName(String inName){ if(inName.equals("") || inName==null) { System.out.println("You have input wrong name,Please try again:"); return false; } else { Name=inName; }}
這裡這個方法用來對類的執行個體域name進行設定,同時為了防止輸出錯誤,我們可以用一個迴圈驅動,直到輸入正確為之。
假設我們已經構造了一個對象, employee1,那麼就可以調用這個方法了:
employee1.setName("volcanol");
調用方法後就將對象的執行個體域name設定為volcanol了;實際上setName在調用的過程中有兩個參數,一個是顯示參數inName
一個是隱式參數,就是方法前的employee1對象,顯示參數在參數列表中給出,隱式參數沒有出現在參數列表中。
在每一個方法中,用關鍵字this表示隱式參數,this參數表示對象本身。例如我們可以這樣編寫方法:
public boolean setName(String inName){ if(inName.equals("") || inName==null) { System.out.println("You have input wrong parment"); return false; } else { this.Name=inName; //顯示的調用了隱式參數this }}
這裡我們可以看到利用更改器方法,可以對輸入參數進行檢驗,可以減少異常出現的機會,因此這也是一種容錯的機制。
【訪問器方法和封裝】
在我們設計的employee類中,設定了幾個訪問器方法:
public String getName() { return Name; } public boolean getGender() { return Gender; } public String getPhoneNumber() { return PhoneNumber; } public double getSalary() { return Salary; }
這些方法有一個特點:方法簡單的返回執行個體域的值,那麼為什麼我們不將執行個體域設計成public屬性,而要設計為private的屬性呢?
這裡在於通常設定好僱員的某些資訊後就不需要再修改,例如名字、生日、住址、社會安全號碼等等資訊,為了防止這些新被意外的修改,我們
就是用這種機制來避免非法的修改。
我們將所有的執行個體域都設計為private的後,而有些內容還需要進行修改,那麼我們就可以根據實際的應用,為類的執行個體域設計:
1、擷取執行個體域訪問器方法
2、修改執行個體域的更改器方法
這樣做是為了提高封裝性,封裝後代碼會變複雜,當然這也是有優勢的:
1、當方法的介面不變的時候,可以對類的實現進行任意的修改,而不會影響對象的使用者。
2、可以對資料進行容錯檢測,例如可以檢查輸入的inName參數是否為空白。
【關於private和final】
接觸過C++的童鞋,應該知道在C++的存取控制策略上面有幾個:public、private、protected等存取控制策略,
在Java中也有幾種存取控制策略:
1、public: 公有存取原則,就是域可以被類的對象自己訪問,也可以被其他類的對象訪問
2、private: 定義為private的域可以被類的對象自己訪問,但是不能被其他類的對象訪問
同時定義為private的方法可以任意修改對象的介面,設定將方法刪除,而不會影響對象使用者造成影響,當然這樣做的時候,
需要類的設計者重新構建類。
因此如果一個類的某個域不想被其他類的對象引用,那麼最合適的方法就是將其設計為private的存取控制策略。
前面說過這個關鍵字:final。 這個關鍵字聲明或者定義的對象和C++語言中的const 變數有點類似,但是又不完全一樣,需要注意
分辨。
在Java中定義為final的對象或者變數,一旦初始化後就不再能改變。這就是說如果一個類中設計了final的執行個體域,那麼必須在類的構造
器中對其進行初始化;同時還需要在以後的引用過程中不對這樣的執行個體域進行改寫,即不能用更改器方法訪問final屬性執行個體域。
例如:
private final String Name;
就是說一個僱員的姓名註冊到公司的資訊系統後除非僱員對象被刪除/登出,否則僱員的Name域就不能改變。
這裡有一點需要說明的:
1、final修飾符一般應用於基礎資料型別 (Elementary Data Type)的域,或者不可變類的資料域。
2、final修飾符修飾可變對象的時候,並不是指對象不可變,這裡容易造成混淆。(是否指的是其引用指向不能改變??這個問題需要繼續研究)。
例如我們設計這樣一個域:
private final Date Birthday;
當用構造器構造對象後,其他對象可以調用Birthday的方法來改變對象的。
【靜態域和靜態方法】
1、靜態域
通過關鍵字static來定義類的靜態域,類中定義靜態域後,類的所有執行個體共用同一塊記憶體代表的靜態域。
例如:
class employee
{
private int id;
private static int nextId=1;
}
如果用這個類定義執行個體化對象,則所有的對象共用一個nextId靜態域空間,一個對象改變這個靜態域則其他對象關於這個
靜態域的引用都將改變。
如果一個類中定義了靜態域,即使不執行個體化對象,靜態域nextId靜態域也存在,靜態域屬於類,而不屬於任何獨立的對象。
這裡還有一個需要注意的地方:
類的非靜態域需要通過類的對象引用,而靜態域可以通過類來引用,即我們可以如下引用靜態域:
employee.nextId=xx;
2、靜態常量
在類中可以定義靜態常量,例如在類Math中定義了一個靜態常量:
public class Math
{
........
public static final double PI=3.14159265358979323846;
..........
}
這樣在程式中不需要執行個體化對象就可以引用這個靜態域常量。例如:
s=r*r*Math.PI; //面積=PI*r^2
而如果將關鍵字省略,則PI變成Math類的一個執行個體域,那時就需要通過Math類的對象訪問PI,並且每一個Math對象
都將有一個PI的副本。
3、靜態方法
靜態方法不能向對象實施操作。我們知道在Math類中有一個pow方法,這個方法就是一個靜態方法,
通過下面的方式來調用pow方法:
Math.pow(x,a) //電腦x^a 的結果,在運算時不使用任何Math對象,即沒有隱式參數this。
靜態方法不能操作對象,所以不能在靜態方法中訪問非靜態執行個體域; 在靜態方法中可以訪問自身類中的靜態域。
例如:
public static int getNextId()
{
return nextId ; // static nextId
}
則可以通過類名調用這個方法:
int n=employee.getNextId();
當然此時我們也可以通過對象調用這個方法: int n1= employee1.getNextId();
通常在下面情況下使用靜態方法:
1、一個方法不需要訪問對象的狀態,其所需的參數通過顯示提供。
2、一個類的方法只需要訪問類的靜態域。
4、main方法
每個類都可以有一個main方法,但是在應用程式中每個類的main方法不一定都被執行。
這裡需要注意,main方法必須定義為static的,同時我們可以單獨對某個類進行測試。
例如定義了一個應用程式application。
public class application
{
statement....
employee employee1=new employee();
}
public class employee
{
public static main(String[] args[])
{
statement......
}
}
我們可以單獨編譯employee類: java employee; 這時僅對employee類進行測試,不會應用程式中的其他類,除非在employee中
引用了其他類。
也可以編譯整個應用程式: java application; 這時employee類中的main方法將不能被執行,也就是說應用程式的可以有多個類擁有
main方法,但是應用程式只有一個入口。
今天就說到這,接下來就是類方法參數的內容了。
這裡還有一個問題不太明白,這裡不知哪位大神解釋一下就是上面的文字中關於:final關鍵字。(是否指的是其引用指向不能改變??這個問題需要繼續研究)。