Day03=面向物件基礎+進階
技術標籤:Java基礎學習筆記
面向物件 Object Oriented
面試常考點:面向物件的特性?
面向物件是一個建模的思路,關注具備功能(函式方法)的物件,把有共同屬性和功能的物件視為一個類,將這些共同的屬性和功能/行為抽象出來,並且封裝進類class
裡實現。如果後面需要做一些工作(需求)的時候,就建立物件(new),讓物件來做這些事情(呼叫方法)。這就很像一個工具。
物件是很厲害的,封裝了一堆你想要實現的功能。你不需要知道這些功能怎麼實現,只要建立物件並且調物件的對應的方法就行。
(spring中的控制反轉就是將建立物件的這個控制權限也交給spring了,只需要提供配置檔案就可以讓spring的容器生成Bean物件。工廠模式
還可能考到的:c++和java的區別?這裡面向過程/面向物件也是一個區別,還可以答指標,記憶體回收等。
面向過程需要關注很繁瑣的過程。而面向物件不用關注實現的具體細節,而是關注統籌架構(巨集觀整體)的問題。
面向物件常考面試題-三大特徵
- 封裝:所有內容對外部不可見(外部只能調方法)
- 繼承:將其他的功能繼承並發展
- 多型:方法的過載本身就是多型性的體現 (相同方法名,不同引數)
還有可能問到的擴充套件問題:多型在類載入的哪個階段?
類與物件
類是共性,是總結起來的總和特徵,物件是個性,是個體。
根據類製造物件。類裡面有抽象出來的共同屬性和方法,定義物件的操作。類必須通過物件才可以使用。
類的定義
public class Demo{
//成員屬性
//成員方法
}
一個.java檔案裡可以存在N個類,但只能存在一個public修飾的類。這表示編譯單元有單一的公共介面。.java的名稱必須與public修飾的類完全一致。(但是內部類可以有public)
記憶體區域
棧
答題要點:
- 可訪問特性:棧中元素執行緒私有,其他棧不可訪問。
- 資料結構特性:先進先出。
- 存取速度:比堆快,僅次於PC暫存器
- (存取快的原因)棧記憶體空間的建立與釋放:棧指標的移動->確定大小和範圍->對資料儲存出現限制->只儲存少部分資料(大部分資料儲存於堆記憶體中)
- 資料儲存的限制:資料大小與生存期都已確定(如何確定?),缺乏靈活性。
- 儲存內容:基本資料型別的資料+引用資料型別的引用
堆
- 儲存內容:類的物件(通過new建立的那些,new是告訴JVM去開闢新的一塊堆記憶體空間去建立新的物件)
- 儲存空間:建立的時候不用管
- 記憶體釋放:當不存在該物件的引用時,視為垃圾,垃圾回收器回收。
方法區
建立物件時,類的資訊+方法就被載入到了方法區裡。
記憶體建立過程
- Book b1 存入棧記憶體,賦值null
- = new Book();放入堆記憶體,得到記憶體地址比如0x1234,則佔記憶體中修改b1的null為引用(0x1234)。
- 先從棧記憶體找b1,得到記憶體地址(引用)0x1234,然後到堆記憶體的相應位置上找物件。
- 複製物件,新增b2進棧記憶體,在棧記憶體中是相同的引用。
- 釋放:先從棧記憶體以後進先出的形式釋放,這樣堆記憶體中的物件就沒有引用,就會被GC。
方法過載
如果一個方法只是定義來運算int型別的,但是此時需要運算double?
類中定義的方法允許過載(相同的方法名稱),限制有:
- 方法名稱相同
- 引數列表長度||型別||順序
如果只是返回值不一樣,不構成方法過載。
匿名
沒有引用名。在棧記憶體中有名字,裡面儲存引用,指向堆記憶體。
如果是匿名物件,只能用一次,因為下一次就找不到堆記憶體的位置了。
直接建立物件並呼叫方法 new Math().sum();
封裝
設定物件的時候會遇見邏輯錯誤,如果直接操作物件,不能避免。封裝的意義就是保護或防止資料無意破壞。就是不讓類以外的程式直接訪問和修改成員屬性。如何實現?
- 隱藏物件的屬性和實現細節(將屬性私有)
- 僅對外公開方法,並且還控制方法的訪問級別
即,將成員屬性修飾為private
這樣別的程式就不能直接操作物件的屬性啦。
在賦值時傳入的引數不符合要求(if判斷),列印錯誤。
this關鍵字
調屬性調方法都行。
Person(){
this("xxx",1);//this呼叫了另一個構造方法
}
Person(String s, int a){
}
- this在一個構造方法中,呼叫另一個構造方法時,必須編寫在第一行,構建完物件之後才能對物件進行操作。(super也有這個特性,原因?)
快捷建立getter和setter
- 放在宣告的屬性後面可以建立(source)
- shift+alt+s也可以
如果有很多員工需要修改同一屬性至同一值region
- 讓region指向一個static變數“北京”
原:private String region
靜態屬性:
private static String region
此時儲存於方法區中,含有自己的記憶體地址,所有的員工物件持有region的記憶體地址。
類載入方面的知識點:
- 被
static
修飾的方法或者變數不需要像之前依賴物件.方法()的形式去訪問。它是在類被載入之後(靜態成員在類載入時載入並初始化然後儲存在方法區)就可以通過類名去訪問了。靜止不動的。不會因為物件多次建立而隨之在記憶體中多次建立(物件公用)。 - 靜態不能訪問非靜態,但是非靜態可以訪問靜態。原因:靜態資源可被呼叫的時機早於非靜態資源。
Emp.region = "";
可以直接通過類名訪問
用一個static int count
並在每個構造方法裡++,則可以列印建立次數。
- main方法的
static
不需要建立物件來呼叫,可以直接用。a的main中直接b.say();
包
- 包=類+介面
- 不同包中類名可以相同,加上包名以避免衝突
- 包限定訪問許可權,有許可權的才能訪問某個包中的類
package name;
- 所有單詞字母小寫,單詞之間.隔開,一般為
com.公司名.專案名.模組名....
(是域名,一般不太會重複)(實際上資料夾分層了)
導包時也可以寫類的全名稱:
java.util.Scanner input = new java.util.Scanner(System.in);
。
同一個包中的其他類使用時也不用導包
許可權修飾符
public
都可以訪問protected
其他包不能訪問default
只有本類和包能訪問,子類都不能private
只有本類中能訪問,包內其他類都不能
程式碼塊
- 構造程式碼塊,(直接寫在class下的{},不是方法)類中的成員程式碼塊,每次物件建立時執行,且在構造方法之前執行。
- 靜態程式碼塊,類中使用
static
修飾的成員程式碼塊。在類載入時執行。程式啟動到關閉只執行一次 - 同步程式碼塊。多執行緒。
- 執行順序:靜態程式碼塊->構造程式碼塊->構造方法
main方法詳解
- public 可以被所有操作呼叫
- static 可以通過類名呼叫
- void 沒有返回值
- main JVM只認這個為程式入口
- String[] args 字串陣列,接受引數(控制檯引數,多個)
輸出看看:
其實這個陣列長度為0,沒有輸出
這些引數是在執行java命令時傳遞的。
java Demo1 haha haha hehe
就可以有輸出了
問題總結
- 棧中的資料大小與生存期是如何確定的?
- 如果複製物件b2=b1,改變b2的屬性,那麼最後打印出來的b1的屬性也會更改,因為指向相同的引用
- super必須放第一行的原因?