《 高淇Java300集視訊》:【3】面向物件基礎
面向過程(Procedure Oriented)和麵向物件(Object Oriented,OO)都是對軟體分析、設計和開發的一種思想,它指導著人們以不同的方式去分析、設計和開發軟體。
面向物件程式設計,是一種通過物件的方式,把現實世界對映到計算機模型的一種程式設計方法。
一、類與物件
類(Class):是對一類事物的描述 ,是抽象的 、概念上的定義。由屬性(Field)、方法(Method)和構造方法(Constructor )組成。
物件(Object):是實際存在的該類事物的每個個體,因而也稱為例項(instance)。
如:“書”是一種抽象的概念,所以它是類,而《Java核心技術》、《Java程式設計思想》是物件。
1.1、定義類
語法:
修飾符 class 類名 { //屬性宣告 //方法宣告 }
1 /** 2 * 測試定義類 3 * @author 林 4 * 5 */ 6 public class TestStudent { 7 String name; //屬性宣告 8 int age; 9 10 void study() { //方法宣告 11 System.out.println("學習中"); 12 } 13 }
1.2、建立物件
語法:
修飾符 資料型別 屬性名 = 初始化值 ;
// 測試建立物件 TestStudent s=new TestStudent();
1.3、屬性
初始化預設值 | |
---|---|
整型 | 0 |
浮點型 | 0.0 |
字元型 | '\u0000' |
布林型 | false |
所有引用型別 |
Java 語言中除基本型別之外的變數型別都稱之為引用型別。
1.4、修飾符
同一個類 | 同一個包 | 子類 | 所有類 | |
---|---|---|---|---|
private | √ | × | × | × |
default(預設) | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ |
1.5、記憶體分析
堆( Heap):儲存物件例項
棧( Stack)
方法區(Method Area) :儲存類資訊、 常量、 靜態變數、 靜態方法、程式碼
二、方法
語法:
修飾符 方法返回型別 方法名(方法引數列表) { 若干方法語句; return 方法返回值; }
2.1、引數
方法可以包含0個或任意個引數。方法引數用於接收傳遞給方法的變數值。呼叫方法時,必須嚴格按照引數的定義一一傳遞。
1 class Group { 2 String[] names; 3 4 public void setNames(String... names) { 5 this.names = names; 6 } 7 }
// 測試可變引數 Group g=new Group(); g.setNames(); //傳0個引數 g.setNames("林一"); //傳1個引數 g.setNames("林一","林二"); //傳2個引數
【1】基本型別引數傳遞,傳遞的是數值。
1 // 測試基本型別引數傳遞 2 public class Main { 3 public static void main(String[] args) { 4 Person p = new Person(); 5 int n = 15; 6 p.setAge(n); //setAge()方法獲得的引數,複製了n的值給p.age,後面n改變不影響p.age 7 System.out.println(p.getAge()); // 列印15 8 n = 20; 9 System.out.println(p.getAge()); // 列印15 10 } 11 } 12 13 class Person { 14 private int age; 15 16 public int getAge() { 17 return this.age; 18 } 19 20 public void setAge(int age) { 21 this.age = age; 22 } 23 }
【2】引用型別引數的傳遞,傳遞的是物件地址。
1 // 測試引用型別引數的傳遞 2 public class TestMethod { 3 public static void main(String[] args) { 4 Person p=new Person(); 5 String[] f=new String[] {"林一","林二"}; 6 p.setName(f); //陣列是一個物件,傳入陣列只是傳引用地址 7 System.out.println(p.getName()); 8 f[1]="林三"; //修改陣列元素 9 System.out.println(p.getName()); //引用地址沒變,陣列元素改變,結果也改變 10 } 11 } 12 13 class Person{ 14 private String[] name; 15 16 public String getName() { 17 return this.name[0]+" "+this.name[1]; 18 } 19 20 public void setName(String[] name) { 21 this.name=name; 22 } 23 }
2.2、方法過載(Overload)
方法名相同,但各自的引數不同,稱為方法過載。
方法過載的目的是,功能類似的方法使用同一名字,更容易記住,因此,呼叫起來更簡單。
2.3、構造方法
構造方法(constructor),是一個建立物件時被自動呼叫的特殊方法,目的是物件的初始化。
【構造方法要點】:
-
通過new關鍵字呼叫。
-
構造方法有返回值,但不能定義返回值型別,不能在構造器裡使用return返回某個值。
-
如沒有定義構造方法,則編譯器會自動定義一個無參的構造方法。如已定義則編譯器不會自動新增。
-
構造器的方法名必須和類名一致。
1 package com.test; 2 /** 3 * 測試定義構造方法 4 * @author 林 5 * 6 */ 7 public class TestStu { 8 public static void main(String[] args) { 9 Stu s=new Stu("林一",17); // 建立物件會自動呼叫構造方法 10 System.out.println(s.getName()); 11 } 12 } 13 14 class Stu{ 15 private String name; 16 private int age; 17 18 public Stu(String name,int age) { //定義構造方法 19 this.name=name; 20 this.age=age; 21 } 22 23 public String getName() { 24 return this.name; 25 } 26 27 public int getAge() { 28 return this.age; 29 } 30 }
【1】預設構造方法
如自定義了一個構造方法,那麼,編譯器就不再自動建立預設構造方法。
構造方法過載,根據不同引數區別不同得構造方法。
1 /* 測試構造方法過載 */ 2 class Person { 3 private String name; 4 private int age; 5 6 public Person(String name, int age) { 7 this.name = name; 8 this.age = age; 9 } 10 11 public Person(String name) { 12 this.name = name; 13 this.age = 12; 14 } 15 16 public Person() { 17 } 18 }
2.4、equals與==方法
Object 的 equals 方法預設就是比較兩個物件的hashcode,是同一個物件的引用時返回 true 否則返回 false。
==代表比較雙方是否相同。如果是基本型別則表示值相等,如果是引用型別則表示地址相等即是同一個物件。
【eclipse把游標放String類,按ctrl鍵+點選滑鼠左鍵看類原始碼】
1 package com.test; 2 3 /** 4 * 測試equals與==方法 5 * @author 林 6 * 7 */ 8 9 public class TestEquals { 10 public static void main(String[] args) { 11 Person p1=new Person(); 12 Person p2=new Person(); 13 System.out.println(p1==p2); //false 14 System.out.println(p1.equals(p2)); //false 15 16 String s1=new String(); 17 String s2=new String(); 18 System.out.println(s1==s2); //false 19 System.out.println(s1.equals(s2)); //true,equals重構過 20 } 21 } 22 23 class Person{ 24 int id; 25 String name; 26 public void showName() { 27 System.out.println(id+" "+name); 28 } 29 }
2.5、toString方法
Object類中定義有public String toString()方法,其返回值是 String 型別。
Object類中toString方法的原始碼為:
1 public String toString() { 2 return getClass().getName() + "@" + Integer.toHexString(hashCode()); 3 }
1 package com.test; 2 /** 3 * 測試toString預設輸出值 4 * @author 林 5 * 6 */ 7 public class TestToString { 8 public static void main(String[] args) { 9 Per p=new Per(); 10 System.out.println(p); 11 } 12 } 13 14 class Per{ 15 String name; 16 int age; 17 }
執行結果:
com.test.Per@15db9742
1 package com.test; 2 /** 3 * 測試重寫toString方法 4 * @author 林 5 * 6 */ 7 public class TestToString { 8 public static void main(String[] args) { 9 Per p=new Per(); 10 p.name="林一"; 11 p.age=18; 12 System.out.println(p); 13 } 14 } 15 16 class Per{ 17 String name; 18 int age; 19 @Override 20 public String toString() { //重寫toString方法 21 return name+" "+age; 22 } 23 }
三、關鍵字
3.1、this關鍵字
在方法內部,可以使用一個隱含的變數this
,它始終指向當前物件。因此,通過this.field
就可以訪問當前物件的欄位。
如果沒有命名衝突,可以省略this
。
1 class Person { 2 private String name; 3 public String getName() { 4 return name; // 相當於this.name 5 } 6 }
1 class Person { 2 private String name; 3 public void setName(String name) { 4 this.name = name; // this不可少,this.name為成員變數 5 } 6 }
3.2、super關鍵字
1 class Student extends Person { 2 public String hello() { 3 return "Hello, " + super.name; //呼叫父類屬性 4 } 5 }
1 class Student extends Person { 2 protected int score; 3 public Student(String name, int age, int score) { 4 super(name, age); // 呼叫父類的構造方法Person(String, int) 5 this.score = score; 6 } 7 }
3.3、static關鍵字
static宣告的方法為靜態方法
-
靜態屬性被該類的所有例項共享,在類被載入時被顯式初始化。
-
靜態屬性使用 “類名.類屬性” 呼叫。
-
靜態方法不需要物件, 就可以呼叫(如:類名.方法名)。
-
呼叫靜態方法時, 不會將物件的引用傳遞給它, 所以在static方法中不可訪問非static的成員。
-
靜態方法不能以任何方式引用this和super關鍵字。
1 /** 2 * 測試static關鍵字 3 * @author 林 4 * 5 */ 6 public class TestStatic { 7 int a; 8 static int width; //靜態成員變數、類屬性 9 10 static void gg() { //靜態方法 11 System.out.println("gg"); 12 } 13 14 void tt() { //普通方法 15 System.out.println("tt"); 16 } 17 18 public static void main(String[] args) { //java程式執行入口 19 TestStatic hi=new TestStatic(); 20 TestStatic.width=2; //呼叫靜態成員變數 21 TestStatic.gg(); //呼叫靜態方法 22 } 23 }
-
如果希望載入後, 對整個類進行某些初始化操作, 可以使用static初始化塊。
-
類第一次被載入時先執行static程式碼塊; 類多次載入時, static程式碼塊只執行一次; Static經常用來進行static變數的初始化。
-
經常用來進行static變數的初始化。
-
靜態初始化塊中不能訪問非static成員。
1 /** 2 * 測試靜態初始化塊 3 * @author 海 4 * 5 */ 6 public class TestStaticBlock { 7 static { //靜態初始化塊,類載入時載入 8 System.out.println("靜態初始化塊"); 9 } 10 11 public static void main(String[] args) { 12 System.out.println("main方法"); 13 } 14 }
3.4、final關鍵字
final作用:
-
修飾變數: 被他修飾的變數不可改變。一旦賦了初值,就不能被重新賦值。
-
修飾方法:該方法不可被子類重寫。但是可以被過載。
-
修飾類: 修飾的類不能被繼承。比如:Math、String等。
四、垃圾回收機制
五、包
包機制是Java中管理類的重要手段,通過包我們很容易對解決類重名的問題,也可以實現對類的有效管理。
【二個要點】:
-
通常是類的第一句非註釋性語句。
-
包名:域名倒著寫即可,再加上模組名,便於內部管理類。
1 package com.test; 2 3 public class TestPerson { 4 5 }
5.1、常用包
說明 | |
---|---|
java.lang | 包含一些Java語言的核心類,如String、Math、Integer、System和Thread,提供常用功能。 |
java.awt | 包含了構成抽象視窗工具集(abstract window toolkits)的多個類,這些類被用來構建和管理應用程式的圖形使用者介面(GUI)。 |
java.net | 包含執行與網路相關的操作的類。 |
java.io | 包含能提供多種輸入/輸出功能的類。 |
java.util |
5.2、匯入類
【要點】:
-
Java會預設匯入java.lang包下所有的類,因此這些類我們可以直接使用。
-
如果匯入兩個同名的類,只能用包名+類名來顯示呼叫相關類。
1 package com.test; 2 /** 3 * 測試匯入同名類的處理 4 * @author 海 5 * 6 */ 7 8 import java.sql.Date; 9 import java.util.*; 10 11 public class Test { 12 public static void main(String[] args) { 13 Date now; 14 java.util.Date now2=new java.util.Date(); //java.util.Date和java.sql.Date類同名,需要完整路徑 15 System.out.println(now2); 16 Scanner input=new Scanner(System.in); 17 } 18 }
5.3、靜態匯入
靜態匯入:其作用是用於匯入指定類的靜態屬性,這樣可以直接使用靜態屬性。
1 package com.test; 2 3 /** 4 * 測試靜態屬性匯入的使用 5 * @author 海 6 * 7 */ 8 9 import static java.lang.Math.*; //匯入Math類的所有靜態屬性 10 import static java.lang.Math.PI; 11 12 public class Test { 13 public static void main(String[] args) { 14 System.out.println(PI); 15 System.out.println(random()); 16 } 17 }