一、類與物件
1.面向物件學習的三條主線
-
Java類及類的成員:屬性、方法、構造器;代碼塊、內部類
-
面向物件的大特征:封裝性、繼承性、多型性、(抽象性)
-
其它關鍵字:this、super、static、final、abstract、interface、package、import等,“大處著眼,小處著手”,
2.面向物件與面向程序
-
面向程序:強調的是功能行為,以函式為最小單位,考慮怎么做,
-
面向物件:強調具備了功能的物件,以類/物件為最小單位,考慮誰來做,
舉例對比:人把大象裝進冰箱,
3.完成一個專案(或功能)的思路
- 根據問題需要,選擇問題所針對的現實世界中的物體,
- 從物體中尋找解決問題相關的屬性和功能,這些屬性和功能就形成了概念世界中的類,
- 把抽象的物體用計算機語言進行述,形成計算機世界中類的定義,即借助某種程式 語言,把類構造成計算機能夠識別和處理的資料結構,
- 將類實體化成計算機世界中的物件,物件是計算機世界中解決問題的最終工具,
4.面向物件中兩個重要的概念
類:對一類事物的描述,是抽象的、概念上的定義
物件:是實際存在的該類事物的每個個體,因而也稱為實體(instance)
-
面向物件程式設計的重點是類的設計
-
設計類,就是設計類的成員,
二者的關系:物件,是由類new出來的,派生出來的,
5.面向物件思想落地實作的規則一
-
創建類,設計類的成員
-
創建類的物件
-
通過“物件.屬性”或“物件.方法”呼叫物件的結構
屬性 = 成員變數 = field = 域、欄位
方法 = 成員方法 = 函式 = method
創建類的物件 = 類的實體化 = 實體化類
6.物件創建與記憶體決議
public static void main(String args[]){
Person p1 = new Person();
Person p2 = new Person();
Person p3 = p1;//沒有新創建一個物件,共用一個堆空間中的物件物體,
Persion p1 =new Persion();
p1.name="Gogo";
p1.isMale=true;
Persion p2=new Persion();
System.out.println(p2.name);//null
Persion p3 = p1;
p3.age = 9;
}
class Persion{
String name;
int age;
boolean isMale;
}
【記憶體決議】

public static void main(String[] args) {
Student[] stus = new Student[3];
stus[0] = new Student();
System.out.println(stus[0].state);//1
System.out.println(stus[1]);//null
System.out.println(stus[1].number);//例外
stus[1] = new Student();
System.out.println(stus[1].number);//0
}
class Student{
int number;//學號
int state;//年級
int score;//成績
}
【記憶體決議】

7.匿名物件
我們創建的物件,沒顯式的賦給一個變數名,即為匿名物件
特點:匿名物件只能呼叫一次,
舉例:
new Phone().sendEmail();
new Phone().playGame();
new Phone().price = 1999;
new Phone().showPrice();//0.0
應用場景:
PhoneMall mall = new PhoneMall();
//匿名物件的使用
mall.show(new Phone());
//其中,
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.playGame();
}
}
8.理解"萬事萬物皆物件"
- 在Java語言范疇中,我們都將功能、結構等封裝到類中,通過類的實體化,來呼叫具體的功能結構
- Scanner,String等、檔案:File、網路資源:URL
- 涉及到Java語言與前端Html、后端的資料庫互動時,前后端的結構在Java層面互動時,都體現為類、物件,
二、類的結構之一:屬性
對比:屬性vs區域變數
1.相同點
-
定義變數的格式:資料型別 變數名 = 變數值
-
先宣告,后使用
-
變數都其對應的作用域
2.不同點
- 在類中宣告的位置的不同
屬性:直接定義在類的一對{}內
區域變數:宣告在方法內、方法形參、代碼塊內、構造器形參、構造器內部的變數
- 關于權限修飾符的不同
屬性:可以在宣告屬性時,指明其權限,使用權限修飾符,
常用的權限修飾符:private、public、預設、protected --->封裝性,
目前,大家宣告屬性時,都使用預設就可以了,
區域變數:不可以使用權限修飾符,
- 默認初始化值的情況:
屬性:類的屬性,根據其型別,都默認初始化值,
整型(byte、short、int、long:0)
浮點型(float、double:0.0)
字符型(char:0 (或'\u0000'))
布爾型(boolean:false)
參考資料型別(類、陣列、介面:null)
區域變數:沒默認初始化值,
意味著,我們在呼叫區域變數之前,一定要顯式賦值,
特別地:形參在呼叫時,我們賦值即可,
- 在記憶體中加載的位置:
屬性:加載到堆空間中 (非static)
區域變數:加載到堆疊空間
三、類的結構至二:方法
1.方法的宣告
權限修飾符 回傳值型別 方法名(形參串列){
方法體
}
方法:描述類應該具有的功能,
比如:Math類:sqrt()\random() \...
Scanner類:nextXxx() ...
Arrays類:sort() \ binarySearch() \ toString() \ equals() \ ...
舉例
public void eat(){}
public void sleep(int hour){}
public String getName(){}
public String getNation(String nation){}
關于權限修飾符:默認方法的權限修飾符先都使用public
Java規定的4種權限修飾符:private、public、預設、protected
回傳值型別: 回傳值 vs 沒回傳值
如果方法回傳值,則必須在方法宣告時,指定回傳值的型別,同時,方法中,需要使用
return關鍵字來回傳指定型別的變數或常量:“return 資料”,
如果方法沒回傳值,則方法宣告時,使用void來表示,通常,沒回傳值的方法中,就不需要
使用return.但是,如果使用的話,只能“return;”表示結束此方法的意思,
我們定義方法該不該回傳值?我們定義方法時,該不該定義形參?
-
題目要求
-
憑經驗:具體問題具體分析
方法名:屬于識別符號,遵循識別符號的規則和規范,“見名知意”
形參串列:方法可以宣告0個,1個,或多個形參,
格式:資料型別1 形參1,資料型別2 形參2,…
方法體:方法功能的體現,
2.方法的多載
定義:在同一個類中,允許存在一個以上的同名方法,只要它們的引數個數或者引數型別不同即可,
總結:"兩同一不同":同一個類、相同方法名
引數串列不同:引數個數不同,引數型別不同
構成多載的舉例
舉例一:
Arrays類中多載的sort() / binarySearch();PrintStream中的println()
舉例二:
//如下的4個方法構成了多載
public void getSum(int i,int j){
System.out.println("1");
}
public void getSum(double d1,double d2){
System.out.println("2");
}
public void getSum(String s ,int i){
System.out.println("3");
}
public void getSum(int i,String s){
System.out.println("4");
}
不構成多載的舉例
//如下的3個方法不能與上述4個方法構成多載
//public int getSum(int i,int j){
// return 0;
//}
//public void getSum(int m,int n){
//
//}
//private void getSum(int i,int j){
//
//}
如何判斷是否構成方法的多載?
嚴格按照定義判斷:兩同一不同,
跟方法的權限修飾符、回傳值型別、形參變數名、方法體都沒關系!
如何確定類中某一個方法的呼叫?
方法名 ---> 引數串列
面試題:方法的多載與重寫的區別?
要是這么問,就跟如下的區別一樣,說清楚各的作用就行了,
throws\throw
String\StringBuffer\StringBuilder
Collection\Collections
final\finally\finalize
抽象類、介面
sleep() / wait()
...
3.可變個數形參的方法
這是jdk 5.0新增的內容
可變個數形參的格式:資料型別 ... 變數名
當呼叫可變個數形參的方法時,傳入的引數個數可以是:0個,1個,2個,,,,
-
可變個數形參的方法與本類中方法名相同,形參不同的方法之間構成多載
-
可變個數形參的方法與本類中方法名相同,形參型別也相同的陣列之間不構成多載,換句話說,二者不能共存,
-
可變個數形參在方法的形參中,必須宣告在末尾
-
可變個數形參在方法的形參中,最多只能宣告一個可變形參,
舉例
public void show(int i){
}
public void show(String s){
System.out.println("show(String)");
}
public void show(String ... strs){
System.out.println("show(String ... strs)");
for(int i = 0;i < strs.length;i++){
System.out.println(strs[i]);
}
}
//不能與上一個方法同時存在
//public void show(String[] strs){
//
//}
呼叫時:
test.show("hello");
test.show("hello","world");
test.show();
test.show(new String[]{"AA","BB","CC"});
4.遞回方法
遞回方法:一個方法體內呼叫它自身,
方法遞回包含了一種隱式的回圈,它會重復執行某段代碼,但這種重復執行無須回圈控制,
遞回一定要向已知方向遞回,否則這種遞回就變成了無窮遞回,類似于死回圈,
舉例
// 例1:計算1-n之間所自然數的和
public int getSum(int n) {// 3
if (n == 1) {
return 1;
} else {
return n + getSum(n - 1);
}
}
// 例2:計算1-n之間所自然數的乘積:n!
public int getSum1(int n) {
if (n == 1) {
return 1;
} else {
return n * getSum1(n - 1);
}
}
//例3:已知一個數列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
//其中n是大于0的整數,求f(10)的值,
public int f(int n){
if(n == 0){
return 1;
}else if(n == 1){
return 4;
}else{
//return f(n + 2) - 2 * f(n + 1);
return 2*f(n - 1) + f(n - 2);
}
}
//例4:斐波那契數列
//例5:漢諾塔問題
//例6:快排
5+2=2*(5+1)+5
7=17
三、類的結構之三:構造器
構造器(或構造方法):Constructor
1.構造器的作用
-
創建物件
-
初始化物件的資訊
2.使用說明
-
如果沒顯式的定義類的構造器的話,則系統默認提供一個空參的構造器
-
定義構造器的格式:權限修飾符 類名(形參串列){}
-
一個類中定義的多個構造器,彼此構成多載
-
一旦我們顯式的定義了類的構造器之后,系統就不再提供默認的空參構造器
-
一個類中,至少會有一個構造器,
3.舉例
//構造器
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
public Person(String n,int a){
name = n;
age = a;
}
4.JavaBean概念
所謂JavaBean,是指符合如下標準的Java類:
-
類是公共的
-
一個無參的公共的構造器
-
屬性,且對應的get、set方法
5.屬性賦值順序
① 默認初始化
② 顯式初始化
③ 構造器中初始化
④ 通過"物件.方法" 或 "物件.屬性"的方式,賦值
以上操作的先后順序:① - ② - ③ - ④
四、關鍵字package/import/this/return
1. package的使用
-
為了更好的實作專案中類的管理,提供包的概念
-
使用package宣告類或介面所屬的包,宣告在源檔案的首行
-
包,屬于識別符號,遵循識別符號的命名規則、規范(xxxyyyzzz)、“見名知意”
-
每"."一次,就代表一層檔案目錄,
舉例一
某航運軟體系統包括:一組域物件、GUI和 Reports 子系統

舉例二:MVC 設計模式
模型層:model 主要處理資料
- 資料物件封裝:model.bean/domain
- 資料庫操作類:model.dao
- 資料庫:model.db
控制層:controller 處理業務邏輯
-
應用界面相關:controller.activity
-
存放 fragment:controller.fragment
-
顯示串列的配接器:controller.adapter
-
服務相關的:controller.service
-
抽取的基類:controller.base
視圖層:view 顯示資料
- 相關工具類:view.utils
- 自定義 view:view.ui
JDK中的主要包介紹:
java.lang:包含一些Java語言的核心類,如String、Math、Interger、System和Thread,提供常用功能
java.net:包含執行與網路相關的操作的類和介面,
java.io:包含能提供多種輸入、輸出功能的類,
java.util:包含一些實用工具類 ,如定義系統特性、介面的集合框架類、使用與日期日歷相關的函式 ,
java.text:包含了一些java格式化相關的類
java.sql: 包含了Java進行JCDC資料庫編程的相關類、介面
java.awt:包含了構成抽象視窗工具集(abstract window toolkits)的多個類,這些類被用來構建和管理應用程式的圖形用戶界面(GUI),B/S C/S
2. import的使用
import:匯入
-
在源檔案中顯式的使用import結構匯入指定包下的類、介面
-
宣告在包的宣告和類的宣告之間
-
如果需要匯入多個結構,則并列寫出即可
-
可以使用"xxx.*"的方式,表示可以匯入xxx包下的所結構
-
如果使用的類或介面是java.lang包下定義的,則可以省略import結構
-
如果使用的類或介面是本包下定義的,則可以省略import結構
-
如果在源檔案中,使用了不同包下的同名的類,則必須至少一個類需要以全類名的方式顯示,
-
使用"xxx.*"方式表明可以呼叫xxx包下的所結構,但是如果使用的是xxx子包下的結構,則仍需要顯式匯入
-
import static:匯入指定類或介面中的靜態結構:屬性或方法,
3.this的使用
可以呼叫的結構:屬性、方法;構造器
this呼叫屬性、方法:
this理解為:當前物件 或 當前正在創建的物件
-
在類的方法中,我們可以使用"this.屬性"或"this.方法"的方式,呼叫當前物件屬性或方法,但是,通常情況下,我們都擇省略"this.",特殊情況下,如果方法的形參和類的屬性同名時,我們必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參,
-
在類的構造器中,我們可以使用"this.屬性"或"this.方法"的方式,呼叫當前正在創建的物件屬性或方法,但是,通常情況下,我們都擇省略"this.",特殊情況下,如果構造器的形參和類的屬性同名時,我們必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參,
this呼叫構造器:
-
我們在類的構造器中,可以顯式的使用"this(形參串列)"方式,呼叫本類中指定的其他構造器
-
構造器中不能通過"this(形參串列)"方式呼叫自己
-
如果一個類中有n個構造器,則最多有 n - 1構造器中使用了"this(形參串列)"
-
規定:"this(形參串列)"必須宣告在當前構造器的首行
-
構造器內部,最多只能宣告一個"this(形參串列)",用來呼叫其他的構造器
4.return的使用
使用范圍:使用在方法體中
作用:
①結束方法
②針對于回傳值型別的方法,使用"return 資料"方法回傳所要的資料,
注意點:return關鍵字后面不可以宣告執行陳述句,
五、面向物件的特征一 封裝性
1.為什么要引入封裝性?
面向物件的特征一:封裝與隱藏
我們程式設計追求“高內聚,低耦合”,
高內聚 :類的內部資料操作細節自己完成,不允許外部干涉;
低耦合 :僅對外暴露少量的方法用于使用,
隱藏物件內部的復雜性,只對外公開簡單的介面,便于外界呼叫,從而提高系統的可擴展性、可維護性,通俗的說,把該隱藏的隱藏起來,該暴露的暴露出來,這就是封裝性的設計思想,
2.問題引入
當我們創建一個類的物件以后,我們可以通過"物件.屬性"的方式,對物件的屬性進行賦值,
這里,賦值操作要受到屬性的資料型別和存盤范圍的制約,除此之外,沒其他制約條件,
但是,在實際問題中,我們往往需要給屬性賦值加入額外的限制條件,
這個條件就不能在屬性宣告時體現,我們只能通過方法進行限制條件的添加,
(比如:setLegs()同時,我們需要避免用戶再使用"物件.屬性"的方式對屬性進行賦值,
則需要將屬性宣告為私有的(private).
此時,針對于屬性就體現了封裝性,
3.封裝性思想具體的代碼體現
體現一:將類的屬性xxx私化(private),同時,提供公共的(public)方法來獲取(getXxx)和設定(setXxx)此屬性的值
private double radius;
public void setRadius(double radius){
this.radius = radius;
}
public double getRadius(){
return radius;
}
體現二:不對外暴露的私有的方法
體現三:單例模式(將構造器私有化)
體現四:如果不希望類在包外被呼叫,可以將類設定為預設的,
4.Java規定的四種權限修飾符
權限從小到大順序為:private < 預設 < protected < public
具體的修飾范圍:
| 修飾符 | 類內部 | 同一個包 | 不同包的子類 | 同一個工程 |
|---|---|---|---|---|
| private | Yes | |||
| (預設) | Yes | Yes | ||
| protected | Yes | Yes | Yes | |
| public | Yes | Yes | Yes | Yes |
4種權限都可以用來修飾類的內部結構:屬性、方法、構造器、內部類,
修飾類只能使用:預設、public
六、JVM記憶體結構
編譯完源程式以后,生成一個或多個位元組碼檔案,
我們使用JVM中的類的加載器和解釋器對生成的位元組碼檔案進行解釋運行,意味著,需要將位元組碼檔案對應的類加載到記憶體中,涉及到記憶體決議,
《jvm規范》

虛擬機堆疊:即為平時提到的堆疊結構,我們將區域變數存盤在堆疊結構中,
堆:我們將new出來的結構(比如:陣列、物件)加載在堆空間中,
補充:物件的屬性(非static的)加載在堆空間中,
方法區:類的加載資訊、常量池、靜態域,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/428449.html
標籤:Java
上一篇:Spring
下一篇:請你說說Spring
