面向對象
封裝的原則
要求使對象之外的部分不能隨意存取對象的內部數據,從而有效避免了錯誤對它的“交叉感染”,使軟件錯誤能局部化,降低排錯難度
繼承
所有的類都繼承自java.lang.Object,一些常用的方法:
equals():比較兩個對象引用時否相同。
getClass():返回對象運行時所對應的類的表示,從而得到相應的信息
toString():返回對象字符串表示
finalize():用於在垃圾收集前清除對象
notify(), notifyall(), wait(): 用於多線程處理中的同步
子類(subclass)對父類(superclass,超類)的繼承
子類不能繼承父類中訪問權限為private的成員變量和方法。
子類可以重寫父類的方法,及命名與父類同名的成員變量。
Java不支持多重繼承
創建子類
class SubClass extends SuperClass {
...
}
成員的隱藏和方法的重寫
子類通過隱藏父類的成員變量和重寫父類的方法,可以把父類的狀態和行為變為自身的狀態和行為。
多態性
子類繼承父類后,同一個方法有不同的表現
體現在兩個方面:方法重載實現的靜態多態性(編譯時多態),方法重寫實現的動態多態性(運行時多態)
重寫方法的調用原則:子類重寫父類的方法,調用子類方法;反之,調用父類的方法
一個對象可以引用子類的實例來調用子類的方法
eg: B繼承A,A的對象a引用B的實例,調用B的方法callme()
1 import java.io.*;
2 class A {
3 void callme() {
4 System.out.println("Inside A's callme()) method");
5 }
6 }
7
8 class B extends A {
9 void callme() {
10 System.out.println("Inside B's callme() method");
11 }
12 }
13
14 public class Dispatch {
15 public static void main(String args[]) {
16 A a = new B(); // 引用子類的實例
17 a.callme();
18 }
19 }
類的實現
類聲明
[public][abstract|final] class className [extends superclassName] [implements interfaceNameList] {}
修飾符public, abstract, final說明類的屬性
className為類的屬性
superclassName為父類的名字
interfaceNameList為類所實現的接口列表
類體
class className
{
[public | protected | private] [static] [final] [transient] [volatile] type variableName; // 成員變量
[public | protected | private] [static] [final | abstract] [native] [synchronized] returnType methodName(
[paramList]) [throws exceptionList] {statements}; //成員方法
}
成員變量
[public | protected | private] [static] [final] [transient] [volatile] type variableName; // 成員變量
static: 靜態變量(類變量)
final: 常量
transient:暫時性變量,用於對象存檔
volatile:共享變量,用於並發線程的共享
成員方法
[public | protected | private] [static] [final | abstract] [native] [synchronized] returnType methodName(
[paramList]) [throws exceptionList] {statements}; //成員方法
static: 類方法,可通過類名直接調用
abstract: 抽象方法,沒有方法體
final:方法不能被重寫
native:集成其他語言的代碼
synchronized:控制多個並發線程的訪問
Java類中的限定詞:
private:類中限定為private的成員,只能被這個類本身訪問。如果構造方法為private,則其他類不能實例化該類。
default:不加任何訪問權限,可以被這個類本身和同一個包中的類訪問。
protected:類中限定為protected的成員,可以被這個類本身、它的子類和同一個包中的其他類訪問。
public:類中被限定為public的成員,可以被所有類訪問。
final關鍵字可以修飾類、類的成員變量和成員方法,但作用不同
修飾成員變量:稱為常量,須給出初始值
修飾成員方法:該方法不能被子類重寫
修飾類:類不能被繼承
super: 訪問父類的成員
訪問父類被隱藏的成員變量,如super.variable;
調用父類中被重寫的方法,如super.Method([paramlist]);
調用父類的構造函數,如super([paramlist]);
eg:
1 import java.io.*;
2 class SuperClass {
3 int x;
4
5 SuperClass() {
6 x = 3;
7 System.out.println("in SuperClass: x = " + x);
8 }
9
10 void doSomething() {
11 System.out.println("in SuperClass.doSomething()");
12 }
13 }
14
15 class SubClass extends SuperClass {
16 int x;
17
18 SubClass() {
19 super();
20 x = 5;
21 System.out.println("in SubClass: x = " + x);
22 }
23
24 void doSomething() {
25 super.doSomething();
26 System.out.println("in SubClass.doSomething()");
27 System.out.println("Super.x = " + super.x + "sub.x = " + x);
28 }
29 }
30
31 public class Inhereritance {
32
33 public static void main(String chars[]) {
34 SubClass sc = new SubClass();
35 sc.doSomething();
36 }
37 }
簡單數據:值類型
復合數據:引用類型
1 import java.io.*;
2 public class PassTest {
3 float ptValue;
4
5 public static void main(String args[]) {
6 int val;
7 PassTest pt = new PassTest();
8 val = 11;
9 System.out.println("Original int Value is:"+val);
10 pt.changeInt(val);
11 System.out.println("Int Value after Change is:"+val);
12 pt.ptValue = 101f;
13 System.out.println("Original ptValue is:"+pt.ptValue);
14 pt.changeObjectValue(pt); // 引用類型的參數
15 System.out.println("ptValue after change is:"+pt.ptValue);
16
17 }
18
19 public void changeInt(int value) {
20 value = 55;
21 }
22
23 public void changeObjectValue(PassTest ref) {
24 ref.ptValue = 99f;
25 }
26 }
簡單數據類型作為參數傳遞時,為值傳遞;復合數據類型作為參數傳遞時,為地址傳遞
方法體
方法的實現。方法體中局部變量若與成員變量同名,局部變量將屏蔽成員變量。
1 import java.io.*;
2 class Variable {
3 int x = 0, y = 0, z = 0; // 類的成員變量
4
5 void init(int x, int y) {
6 this.x = x;
7 this.y = y;
8 int z = 5; // 局部變量
9 System.out.println("** in init**");
10 System.out.println("x = " + x + "y = " + y + "z = " + z);
11 }
12 }
13
14 public class VariableTest {
15 public static void main(String args[]) {
16 Variable v = new Variable();
17 System.out.println("** before init **");
18 System.out.println("x = " + v.x + "y = " + v.y + "z = " + v.z);
19 v.init(20, 30);
20 System.out.println("** after init **");
21 System.out.println("x = " + v.x + "y = " + v.y + "z = " + v.z);
22 }
23 }
方法重載
指多個方法享有相同的名字。這些方法的參數必須不同。且參數類型區分度要足夠:如不能使同一簡單類型的數據:int與long
1 import java.io.*;
2
3 class MethodOverloading {
4 void receive(int i) {
5 System.out.println("Receive in data");
6 System.out.println("i = " + i);
7 }
8
9 void receive(int x, int y) {
10 System.out.println("Receive two in datas");
11 System.out.println("x = " + x + "y = " + y);
12 }
13 }
14
15 public class MethodOverloadingTest {
16 public static void main(String args[]) {
17 MethodOverloading mo = new MethodOverloading();
18 mo.receive(1);
19 mo.receive(2, 3);
20 }
21 }
構造方法
一個特殊的方法。每個類都有構造方法,用來初始化該類的一個對象。
構造方法具有和類名相同的名稱,不返回任何數據類型。
重載經常用於構造方法。
構造方法只能由new運算符調用
抽象類和抽象方法:
用abstract關鍵字修飾類:抽象類
用abstract關鍵字修飾方法:抽象方法
抽象類必須被繼承,抽象方法必須被重寫
抽象方法只需聲明,無需實現
抽象類不能被實例化,抽象類不一定要包含抽象方法
若類中包含抽象方法,給類必須被定義為抽象類
接口
接口是抽象類的一種,只包含常量和方法的定義,沒有變量和方法的實現,且其方法都是抽象方法。
用處體現在:
通過接口,實現不相關類的相同行為
通過接口,指明多個類需要實現的方法
通過接口,了解對象的交互界面,無需了解對象所對應的類
接口的定義:
接口聲明:
[public] interface interfaceName[extends listOfSuperInterface] {...}
方法體定義:
returnType methodName([paramlist]);
接口的實現:
在類的聲明中用implements子句來表示一個類使用某個接口
類體中可以使用接口中定義的常量,必須實現接口中定義的所有方法
一個類可以實現多個接口,在implements中用逗號隔開
接口類型的使用:
接口作為一種引用類型來使用
任何實現該接口的類的實例,都可以存儲在該接口類型的變量中,通過這些實例,訪問該類接口中的方法。