java程式設計--孫鑫java無難事Lesson2《位元運算及物件導向程式設計》
1.位元運算
Java中有三個移位元運算符
左移:<<
帶符號右移:>>
無符號右移:>>>這部分內容可參見任何一本電腦作業系統或者電腦導論類書籍。
位元運算測試程式如下:
//***********************************
class Test{public static void main(String[] args) { int i=0xFFFFFFFF;//-1 int c=i<<2; int d=i>>2;//有符號右移 int e=i>>>2;//無符號右移 System.out.println(i);//-1 System.out.println(c);//-4 System.out.println(Integer.toHexString(c));//有符號左移 fffffffc System.out.println(Integer.toHexString(d));//有符號右移 ffffffff System.out.println(Integer.toHexString(e));//無符號右移 3fffffff}}
//***********************************
2.物件導向的概念
(1)概念
簡單的說,物件導向編程(Object Oriented Programming,簡稱OOP)描述的是對象之間的相互作用。物件導向編程與面向過程編程的區別:過程化程式設計先確定演算法,再確定資料結構;物件導向編程先確定資料結構,再確定運算。面向過程編程的程式員,習慣於建立資料結構存放資料並定義方法(函數)來操作資料;物件導向編程的程式員則構造一個物件模型,將資料與方法組織在一起。
(2)物件導向解決問題-計算矩形周長和面積
Rectangle類測試程式如下:
//***********************************
class Rectangle{int w,l;int perimeter(){ return 2*(l+w);}int area(){ return l*w;}public static void main(String[] args) { Rectangle rect1=new Rectangle();Rectangle rect2=new Rectangle();rect1.l=10;rect1.w=5;rect2.l=4;rect2.w=6;System.out.println("the perimeter of rect1 is "+rect1.perimeter());//the perimeter of rect1 is 30System.out.println("the area of rect2 is "+rect2.area());//the area of rect2 is 24}}
//***********************************
3.建構函式
(1)預設建構函式,查看一個類的函數和成員列表通過如下指令:
F:\java\JavaLesson\Lesson2>javap Point
//***********************************
獲得資訊為
//***********************************
Compiled from "Point.java"
class Point {
int x;
int y;
Point();//預設建構函式
void output();
public static void main(java.lang.String[]);
}
//***********************************
(2)預設建構函式提供的預設值
數值型 0
boolean false
char '\0'
對象 null
(3)子類不能繼承父類的建構函式
子類的建構函式會預設調用父類的不帶參數的建構函式,super();如果父類不存在不帶參數的建構函式則發生錯誤,錯誤資訊如下:
Animal.java:33: 錯誤: 無法將類 Animal中的構造器 Animal應用到給定類型;
需要: int,int
找到: 沒有參數
原因: 實際參數列表和形式參數列表長度不同
(4)this調用本類其他建構函式時必須為第一條語句,否則錯誤資訊如下:
Point.java:9: 錯誤: 對this的調用必須是構造器中的第一個語句this(1,1);
4.new 關鍵字的作用
a.為對象分配記憶體空間
b.引起物件建構方法的調用
c.為對象返回一個引用
5.static靜態方法與靜態成員變數
(1)概述
靜態方法和靜態變數是屬於某一個類,而不屬於類的對象。靜態方法和靜態變數的引用直接通過類名引用。
在靜態方法中不能調用非靜態方法和引用非靜態成員變數。反之,則可以。
可以用類的對象obj去調用靜態方法method(),如:obj.method()。
(2)靜態成員函數中訪問非靜態成員變數引起錯誤,錯誤碼及資訊如下:
static void output()
{
System.out.println("output called!");
System.out.println(x);
System.out.println(y);
}
Point.java:29: 錯誤: 無法從靜態上下文中引用非靜態 變數 x
System.out.println(x);
^
Point.java:30: 錯誤: 無法從靜態上下文中引用非靜態 變數 y
System.out.println(y);
(3)常量的初始化
常量由關鍵字final定義,必須賦初值,定義為非靜態時可以放在建構函式中,
而為了避免每個對象的拷貝該資料則可以聲明為靜態,可以共用的資料,此時必須在定義時初始化.
定義 final double PI;而沒有初始化時,錯誤資訊如下
Point.java:14: 錯誤: 可能尚未初始設定變數PI
靜態常量聲明形如:static final double PI=3.1415926;
Point類測試程式如下:
//***********************************
class Point{ int x,y;//物件變數static int z;//類變數屬於類本身,不屬於某個對象//常量必須賦初值 3.1415926 定義為非靜態時可以放在建構函式中 //定義為靜態 共用該資料 避免每個對象的拷貝 此時必須在定義時初始化static final double PI=3.1415926;//靜態常量必須再此初始化Point(){ //PI=3.1415926;//ok 非靜態常量可以這裡初始化 this(1,1);//調用帶參數的建構函式 必須為第一條語句}Point(int a,int b){ //PI=3.1415926;//ok 非靜態常量可以這裡初始化 x=a; y=b;}void output(int x,int y){ this.x=x; this.y=y;//內部成員變數被隱藏 這裡只是形參可見 因此採用this}/*//執行個體方法void output(){ System.out.println(x); System.out.println(y);}*//*//靜態方法static void output(){ System.out.println("output called!"); System.out.println(x);//error 靜態方法引用非靜態成員變數 System.out.println(y);//error}*/static void output(){ System.out.println("output called!"); System.out.println(z);}public static void main(String[] args) { /* Point pt;pt=new Point();pt.x=10;pt.y=10;pt.output();//輸出類的成員變數資訊*//*Point pt; pt=new Point(3,3);pt.output(5,5);pt.output();//result 3,3 使用this解決函數參數和成員變數的重名問題/*Point pt;pt=new Point();pt.output();//result 1,1 預設不帶參數建構函式可以調用帶參數的建構函式*//*Point pt; pt=new Point();Point pt2=new Point();pt.x=6;pt2.x=7;System.out.println(pt.x); System.out.println(pt2.x);//方法只有一份拷貝 而資料成員卻有兩份不同的拷貝*//*//靜態函數 static void output() 的調用Point.output();//直接通過類調用pt=new Point();pt.output();//對象調用靜態方法實質還是通過類調用*//*//靜態變數z的共用Point pt1=new Point();Point pt2=new Point();pt1.z=6;pt2.z=7;//pt1和pt2共用 z變數System.out.println(pt1.z);// result 7 System.out.println(pt2.z);// result 7*/}}
//***********************************
6.特殊變數this--類自身的引用
關於執行個體方法和執行個體資料成員的進一步說明
一個類所有的執行個體(對象)調用的成員方法在記憶體中只有一份拷貝,儘管在記憶體中可能有多個對象,而資料成員在類的每個對象所在記憶體中都存在著一份拷貝。this變數允許相同的執行個體方法為不同的對象工作。每當調用一個執行個體方法時,this變數將被設定成引用該執行個體方法的特定的類對象。方法的代碼接著會與this所代表的對象的特定資料建立關聯。
7.特殊變數super-實現父類成員變數和函數的引用
特殊變數super,提供了對父類的訪問。
可以使用super訪問父類被子類隱藏的變數或覆蓋的方法。
每個子類構造方法的第一條語句,都是隱含地調用super(),
如果父類沒有這種形式的建構函式,那麼在編譯的時候就會報錯。
Animal和Fish類測試程式如下:
//***********************************
class Animal{ int height,weight;/*//建構函式不能被繼承Animal(){System.out.println("animal construct");//先調用基類建構函式}*/Animal(int x, int y){System.out.println("animal construct");//先調用基類建構函式}void Eat(){System.out.println("animal eat");}void Sleep(){System.out.println("animal sleep");}void Breath(){System.out.println("animal breath");}}//java 不允許多繼承class Fish extends Animal{ int height;Fish(){ //super();//隱含調用不帶參數建構函式super(30,30);//調用父類帶參數的建構函式System.out.println("fish construct");//後調用衍生類別建構函式}void Breath()//函數的覆蓋 發生在父類與子類之間 函數的重載在一個類內{ //super.Breath(); //調用父類方法super.height=40;//調用父類成員變數System.out.println("fish bubble");}}class Integration{ static void fn(Animal an){ an.Breath();}public static void main(String [] args){ //Animal an=new Animal();Fish fh=new Fish();//fh.height=30;//fh.weight=30; //an.Breath();//fh.Breath();//多態性//子類有則調用子類,無則調用父類/*Animal an;Fish fh=new Fish();an=fh; Integration.fn(an);//實際調用子類Breath方法 *//*//類型判斷Animal an=new Animal(30,40);Fish fh=new Fish();//Fish 是Animal Animal 不是Fishif(an instanceof Animal ){ System.out.println("Animal instance");}if(fh instanceof Fish ){ System.out.println("fish instance");}*//* Animal an=new Animal(30,40);Fish fh=new Fish();an=fh;if(an instanceof Fish ){ System.out.println("an is Fish instance");//an雖然聲明為Animal但賦值為Fish引用 an is Fish instance}else{ System.out.println("an is Animal instance");}if(fh instanceof Animal ){ System.out.println("fh is Animal instance");//Fish 是Animal fh is Animal instance}else{ System.out.println("fh is fish instance");}*/}}
//**********************************