1. 對象的概念及面向對象的三個基本特征
面向對象的三大核心特性
面向對象開發模式更有利於人們開拓思維,在具體的開發過程中便於程序的划分,方便程序員分工合作,提高開發效率。面向對象程序設計有以下優點。
- 可重用性:它是面向對象軟件開發的核心思路,提高了開發效率。面向對象程序設計的抽象、繼承、封裝和多態四大特點都圍繞這個核心。
- 可擴展性:它使面向對象設計脫離了基於模塊的設計,便於軟件的修改。
- 可管理性:能夠將功能與數據結合,方便管理。
該開發模式之所以使程序設計更加完善和強大,主要是因為面向對象具有繼承、封裝和多態 3 個核心特性。
繼承性
如同生活中的子女繼承父母擁有的所有財產,程序中的繼承性是指子類擁有父類數據結構的方法和機制,這是類之間的一種關系;繼承只能是單繼承。
例如定義一個語文老師類和數學老師類,如果不采用繼承方式,那么兩個類中需要定義的屬性和方法.
語文老師類和數學老師類中的許多屬性和方法相同,這些相同的屬性和方法可以提取出來放在一個父類中,這個父類用於被語文老師類和數學老師類繼承。當然父類還可以繼承別的類,
學校主要人員是一個大的類別,老師和學生是學校主要人員的兩個子類,而老師又可以分為語文老師和數學老師兩個子類,學生也可以分為班長和組長兩個子類。
使用這種層次形的分類方式,是為了將多個類的通用屬性和方法提取出來,放在它們的父類中,然后只需要在子類中各自定義自己獨有的屬性和方法,並以繼承的形式在父類中獲取它們的通用屬性和方法即可。
封裝性
封裝是將代碼及其處理的數據綁定在一起的一種編程機制,該機制保證了程序和數據都不受外部干擾且不被誤用。封裝的目的在於保護信息,使用它的主要優點如下。
- 保護類中的信息,它可以阻止在外部定義的代碼隨意訪問內部代碼和數據。
- 隱藏細節信息,一些不需要程序員修改和使用的信息,比如取款機中的鍵盤,用戶只需要知道按哪個鍵實現什么操作就可以,至於它內部是如何運行的,用戶不需要知道。
- 有助於建立各個系統之間的松耦合關系,提高系統的獨立性。當一個系統的實現方式發生變化時,只要它的接口不變,就不會影響其他系統的使用。例如 U 盤,不管里面的存儲方式怎么改變,只要 U 盤上的 USB 接口不變,就不會影響用戶的正常操作。
- 提高軟件的復用率,降低成本。每個系統都是一個相對獨立的整體,可以在不同的環境中得到使用。例如,一個 U 盤可以在多台電腦上使用。
Java 語言的基本封裝單位是類。由於類的用途是封裝復雜性,所以類的內部有隱藏實現復雜性的機制。Java 提供了私有和公有的訪問模式,類的公有接口代表外部的用戶應該知道或可以知道的每件東西,私有的方法數據只能通過該類的成員代碼來訪問,這就可以確保不會發生不希望的事情。
多態性
面向對象的多態性,即“一個接口,多個方法”。多態性體現在父類中定義的屬性和方法被子類繼承后,可以具有不同的屬性或表現方式。多態性允許一個接口被多個同類使用,彌補了單繼承的不足。
2. Java認識類和對象
類的定義
[訪問權限修飾符] class 類名 {
屬性/ 成員變量/ 字段
行為/ 成員方法
}
類的理解:
1.類是用來描述現實事物的,是Java語言的最基本單位
2.類是抽象的,是由多個對象抽象想象的部分而來
3.類可以理解為一個模板,數屬性和行為的集合,可以通過類的模板創建具體的對象
4.Java使用class來描述一個類
5.類的本質用來組織代碼(方法歸類),封裝數據的(理解提高成員變量的安全性)。
對象的理解:
1.對象是客觀存在的,萬事萬物皆是對象
2.對象是在類的基礎上創建的
3.對象又稱為 實例/引用/變量/對象
如何創建一個對象?
格式: 類名 對象名 = new 類名();
如何訪問一個對象?
訪問成員
對象.成員變量
對象.成員方法
定義一個類的步驟
1、定義類名
2、編寫類的屬性
3、編寫類的方法
4、創建對象
5、通過對象訪問成員
匿名對象
概念: 沒有名字的對象,本質還是一個對象
匿名對象的特點:
1.既然是對象,同樣可以訪問成員
2.匿名對象只能夠使用一次,如果需要使用多次,必須使用變量接收
3.匿名對象一旦使用一次完畢,立刻成為垃圾對象,等待垃圾回收期在空閑的時候回收,節約內存資源
4.匿名對象在Java里一般用於訪問一次的情況,簡化代碼,在Android里節約內存資源
1 public class OOPDemo04 { 2 @SuppressWarnings("resource") 3 public static void main(String[] args) { 4 Student s1 = new Student(); 5
6 // new Student(); 7 //
8 // System.out.println(new Student().name); 9 //
10 // new Student().print99MulTable();
11
12 new Student().name = "隔壁老王"; 13 System.out.println(new Student().name); // null
14
15 String line = new Scanner(System.in).next(); 16 System.out.println(line); 17
18 new Test().method(new Student()); 19 } 20 } 21
22 class Test { 23 public void method(Student s) { 24 System.out.println(s.name); 25 } 26 } 27
28 結果 null
3. Java類的定義及定義類時可用的關鍵字
在 Java 中定義一個類,需要使用 class 關鍵字、一個自定義的類名和一對表示程序體的大括號。完整語法如下:
1 [public][abstract|final]class<class_name>[extends<class_name>] 2 [implements<interface_name>] 3 { 4 //定義屬性部分
5 <property_type><property1>; 6 <property_type><property2>; 7 <property_type><property3>; 8 … 9 //定義方法部分
10 function1(); 11 function2(); 12 function3(); 13 … 14 }
上述語法中各關鍵字的描述如下。
public:表示“共有”的意思。如果使用 public 修飾,則可以被其他類和程序訪問。每個 Java 程序的主類都必須是 public 類,作為公共工具供其他類和程序使用的類應定義為 public 類。abstract:如果類被 abstract 修飾,則該類為抽象類,抽象類不能被實例化,但抽象類中可以有抽象方法(使用 abstract 修飾的方法)和具體方法(沒有使用 abstract 修飾的方法)。繼承該抽象類的所有子類都必須實現該抽象 類中的所有抽象方法(除非子類也是 抽象類)。final:如果類被 final 修飾,則不允許被繼承。class:聲明類的關鍵字。class_name:類的名稱。extends:表示繼承其他類。implements:表示實現某些接口。property_type:表示成員變量的類型。property:表示成員變量名稱。function():表示成員方法名稱。
4. 形參和實參及成員變量和局部變量
1、形參和實參
關於方法的參數,經常會提到形參與實參,形參是定義方法時參數列表中出現的參數,實參是調用方法時為方法傳遞的參數。
1 public int returnMin(int m,int n) 2 { 3 return Math.min(m,n); //m和n是形參
4 } 5 public static void main(String[] args) 6 { 7 int x=50; 8 int y=100; 9 Test t=new Test(); 10 int i=t.returnMin(x,y); //x和y是實參
11 System.out.println(i); 12 }
2、方法的形參和實參具有以下特點:
- 形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只有在方法內部有效,方法調用結束返回主調 方法后則不能再使用該形參變量。
- 實參可以是常量、變量、表達式、方法等,無論實參是何種類型的量,在進行方法調用時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值、輸入等辦法使實參獲得確定值。
- 實參和形參在數量、類型和順序上應嚴格一致,否則會發生“類型不匹配” 的錯誤。
- 方法調用中發生的數據傳送是單向的,即只能把實參的值傳送紿形參,而不能把形參的值反向地傳送給實參。因此在方法調用過程中,形參的值發生改變,而實參中的值不會變化。
3、在調用成員方法時應注意以下 4 點:
- 對無參成員方法來說,是沒有實際參數列表的(即沒有 paramList),但方法名后的括號不能省略。
- 對帶參數的成員方法來說,實參的個數、順序以及它們的數據類型必須與形式參數的個數、順序以及它們的數據類型保持一致,各個實參間用逗號分隔。實參名與形參名可以相同,也可以不同。
- 實參也可以是表達式,此時一定要注意使表達式的數據類型與形參的數據類型相同,或者使表達式的類型按 Java 類型轉換規則達到形參指明的數據類型。
- 實參變量對形參變量的數據傳遞是“值傳遞”,即只能由實參傳遞給形參,而不能由形參傳遞給實參。程序中執行到調用成員方法時,Java 把實參值復制到一個臨時的存儲區(棧)中,形參的任何修改都在棧中進行,當退出該成員方法時,Java 自動清除棧中的內容。
4、方法體中的局部變量
在方法體內可以定義本方法所使用的變量,這種變量是局部變量。它的生存期與作用域是在本方法內,也就是說,局部變量只能在本方法內有效或可見,離開本方法則這些變量將被自動釋放。
在方法體內定義變量時,變量前不能加修飾符。局部變量在使用前必須明確賦值,否則編譯時會出錯。另外,在一個方法內部,可以在復合語句中定義變量,這些變量只在復合語句中有效。
5、成員變量和局部變量的區別
1.定義的位置不同
成員變量: 類體以內,方法體以外
局部變量: 方法的聲明上,或者方法體內
2.在內存的位置不一樣
成員變量: 在堆區分配內存
局部變量: 在棧區分配內存
3.初始化值不一樣
成員變量: 系統賦予初始值
byte short int long 0
float double 0.0
boolean false
char \u0000
引用類型 null
局部變量: 方法的聲明上,或者方法體內
沒有默認值,必須先聲明再賦值再使用
4.變量的生命周期不一樣
生命周期: 變量從開始創建到銷毀的全過程
成員變量: 隨着對象的創建而創建,隨着垃圾回收器回收對象的時候銷毀
局部變量: 隨着方法的調用而創建,隨着方法調用結束而銷毀
5.當成員變量和局部變量重名的時候,局部變量優先,就近原則
如果希望訪問成員變量,需要使用this關鍵字
5.Java方法:Java方法的聲明和調用
構造方法
為什么需要學習構造方法?
1.假設一個類中有100個屬性,一個一個set很麻煩
構造方法: 構造方法本身就是一個特殊的方法而已
1.能夠快速初始化成員變量的值
2.能夠為對象分配內存空間 + new
構造方法的格式:
1 [訪問權限修飾符] 方法名(參數列表) { 2 方法體; 3 // return 值;
4 return; 5 }
構造方法的特點:
1.構造方法沒有返回值,連void都沒有
2.構造方法也是方法,存在方法重載
3.構造方法是用來給成員快速初始化的
4.構造方法方法名必須和類名保持一致
構造方法的注意事項:
1.如果我們沒有書寫構造方法,系統會幫我們書寫一個無參構造方法
2.如果你一旦書寫了一個帶參構造方法,就會覆蓋系統的無參構造方法
3.養成一個好習慣: 每次書寫一個bean的時候,都寫上無參構造方法
好處:
1.無參構造方法能夠初始化默認成員的值
2.反射中調用的就是無參構造方法,很多框架中都會利用反射技術創建對象,反射大部分都是依賴無參構造方法
類的組成
class 類 {
成員變量
構造方法
構造方法重載
成員方法
普通方法
讀寫方法 (get/set方法)
}
1 public class ConstructorDemo01 { 2 public static void main(String[] args) { 3 Student s = new Student(); 4 s.setName("張三"); 5 s.setAge(18); 6 s.show(); 7
8 Student s2 = new Student("李四", 20, "男"); 9 s2.show(); 10
11 } 12 } 13
14 class Student { 15 private String name; 16 private int age; 17 private String gender; 18
19 public Student() { 20 } 21
22 public Student(String name, int age) { 23 this.name = name; 24 this.age = age; 25 } 26
27 public Student(String name, int age, String gender) { 28 this.name = name; 29 this.age = age; 30 this.gender = gender; 31 } 32
33 public String getName() { 34 return name; 35 } 36 public void setName(String name) { 37 this.name = name; 38 } 39 public int getAge() { 40 return age; 41 } 42 public void setAge(int age) { 43 this.age = age; 44 } 45
46 public String getGender() { 47 return gender; 48 } 49
50 public void setGender(String gender) { 51 this.gender = gender; 52 } 53
54 public void show() { 55 System.out.println("Student [name=" + name + ", age=" + age + ", gender=" + gender + "]"); 56 } 57
58
59
60 }
Student [name=張三, age=18, gender=null]
Student [name=李四, age=20, gender=男]
