標籤:成員 記憶體模型 err 等等 次數 llb struct 支援 series
物件導向
物件導向:適合大型的複雜的項目,比如造一輛車,把各個組件(對象):輪子,車架,玻璃等等拼起來完成一整輛車的製造 (需要協作)
面向過程:適合簡單的項目,比如開車,按照一定的過程,1.2.3.4, 第一步打火,第二步掛檔,第三步啟動,一步一步進行下去 (不需要協作)
這兩種思想是相輔相成的,即使我們現在都是物件導向的思想,但你在構建每一個對象時,也是利用面向過程的思想把一個對象構建好。
對象和類
對象裡麵包含它的屬性和行為,屬性就是對象包含的變數,行為就是對象包含的方法。所以對象包含變數和方法。
類,就是對象的模板。例如,所有的狗都有四條腿 (相同的屬性),都會叫(相同的行為),所以哈士奇,吉娃娃都屬於狗這個類。
記憶體分析:棧stack,堆heap,方法區method area
JVM就包含棧,堆,方法區也包含在堆中
棧:棧表示方法執行的記憶體模型。每次調用方法,建立一個棧幀。JVM會為每一個線程建立一個棧,棧屬於每一個線程私人,不能共用。棧的儲存特點是連續儲存空間,先進先出,後進後出。系統會自動分配棧,速度很快。
堆:存放建立好的對象和數組,就一個,所有線程可以共用。不連續記憶體空間,速度慢。
方法區(靜態區):實際也是堆,用於儲存類,常量的資訊(不變的東西)。
構造器(構造方法)(constructor)
1.構造方法名稱必須和類的名字保持一致。
2.通過new關鍵字調用
3.不能用return傳回值
4.如果不定義構造器,系統會自動定義一個無參的構造器
this表示建立好的對象,所以this可以用於區別成員變數和局部變數。this不能用在static類和方法中,前面記憶體分析講了,靜態變數和方法是屬於類的,不屬於對象,所以this指不到任何對象。
JAVA的記憶體回收機制
1.發現無用對象
2.回收無用對象佔用的空間
回收很簡單,但是如何發現呢?主要靠以下兩種演算法:
1. 引用計數法
每一次對象被某個變數引用,都記錄一次。通過記錄被引用次數確定是否為垃圾。但是,當兩個對象循環參考,計數器無法偵察。
2. 引用可達法
把程式所有參考關聯性做一張圖,用演算法對對象的引用進行跟蹤,看是否可達。如果不可到達,則為無用對象。
Static關鍵字
static修飾的成員變數和方法,屬於類,不屬於對象。普通的變數和方法都屬於對象。
靜態方法無法調用普通方法和普通變數。普通方法和變數可以調用靜態。因為靜態屬於類,有類不一定有對象;但有對象一定有類。
JAVA的包,package的使用
JAVA的包,類似於電腦中的檔案夾。一般在類的第一句話,把網域名稱倒著寫。
右鍵 - new - package也可以建包
一定要加包,方便管理,不要使用預設包
package cn.authorxpublic class Test { System.out.println("Hello World!")}
物件導向三大特性:繼承,封裝,多態
繼承,instance of 判斷從屬關係
public class Main { public static void main(String[] args) { Student student = new Student(); student.name = "Jason"; student.major = "Finance"; student.studentID = "001"; System.out.println(student.name + "is a student, his ID is " + student.studentID + " and his major is " + student.major ); student.study(); student.rest(); System.out.println(student instanceof Person); } static class Person{ String name; String major; public void rest(){ System.out.println("take a break!"); } } static class Student extends Person{ String studentID; public void study(){ System.out.println("I am studying now!"); } }}運行結果:Jasonis a student, his ID is 001 and his major is FinanceI am studying now!take a break!true
封裝
存取權限
工作中一般使用許可權的規則:
1. 對於類的屬性,一般直接用private,然後用getter and setter訪問
public class computer{ private int seriesnumber; private String model; private String brand; }
2. 對於類裡面的方法,除特殊情況,一般用public
多態
同一方法的調用,由於其中的對象不同,可能會有不同的行為。比如人.休息()這個方法,有的人可能睡覺,有的人看書,有的人玩遊戲,不同的人對“休息”可能有不同的表現,這就是對象不同,行為可能不同。
要點:
1、多態指方法的多態,不是屬性的多態,與屬性無關
2、多態存在的三個必要條件:繼承,方法重寫,父類引用指向子類對象
3、父類引用指向子類對象後,用該父類引用調用子類重寫的方法,此時多態就出現了
/** *測試多態 */public class Main { public static void main(String[] args) { Animal a = new Animal(); animalCry(a); Dog d = new Dog(); animalCry(d); //父類引用指向了子類對象,調用了子類的方法 } static void animalCry(Animal a){ a.shout(); } static class Animal{ public void shout(){ System.out.println("叫了一聲!"); } } static class Dog extends Animal{ public void shout(){ System.out.println("汪汪汪!"); //繼承和重寫方法 } } class Cat extends Animal{ public void shout(){ System.out.println("喵喵喵!"); //繼承和重寫方法 } }}
抽象類別/抽象方法
抽象類別: 包含了抽象方法的類
抽象方法: 只有方法的聲明, 沒有方法體
要點:
1.、有抽象方法的類只能定義為抽象類別
2.、抽象類別不能執行個體化,不能用new來執行個體化抽象類別
3、抽象類別可以包含屬性,方法,構造方法。構造方法也不能用new來執行個體,只能用來被子類調用
4、抽象類別只能用來繼承
5、抽象方法必須被子類實現
/** * 抽象類別/抽象方法 */public abstract class Animal { public abstract void run(); //有方法,沒有方法體}class Cat extends Animal { @Override public void run() { System.out.println("貓一路小跑...."); //子類必須重寫方法 }}
介面
/** *介面 * 介面是什嗎? 介面就是一種規範,定義了一組規則,表示“如果你是...你就必須可以...”這一思想 介面的意義在於把設計和實現徹底分離 介面支援多繼承 *//** 把設計和實現徹底分離到底有什麼好處? 例如:如何描述飛機,飛彈,籃球,石頭之間的關係?,如果用抽象類別,繼承,他們之間關係很有限 如果用介面共同描述他們都能 “飛” 這一行為,將會非常容易 */public interface MyInterface { //介面中只有:常量和抽象方法! int Max_SPEED = 10000; int Max_HEIGHT = 1; public void fly();}class Plane implements MyInterface { @Override public void fly() { System.out.println("飛機在飛"); }}class Basketball implements MyInterface { @Override public void fly() { System.out.println("籃球在飛"); }}
回調 callback (hook 鉤子函數)
先寫個介面
interface IMyFrame { void paint();}
/** * 回調callback (hook 鉤子函數) */public class PaintFrame { public static void drawFrame(IMyFrame f){ System.out.println("Launch..."); System.out.println("Preparing..."); f.paint(); //調用paint方法 } /**上面這段代碼只留下了一個paint方法,具體怎麼實現要看你傳給他什麼對象,傳什麼用什麼,本質是一種多態的實現。 * 這裡這個paint方法有點像個鉤子,你往上掛什麼,他實現什麼,所以又叫鉤子函數*/ static class GameFrame01 implements IMyFrame{ public void paint(){ System.out.println("Painting GameFrame01..."); //實現介面,重寫方法 } } static class GameFrame02 implements IMyFrame{ public void paint(){ System.out.println("Painting GameFrame02..."); } } public static void main(String[] args) { drawFrame(new GameFrame01()); //調用方法,new一個新的對象 }}
內部類 Innerclass
優點:
1、更好的封裝,只允許外部類直接存取,不允許其他類直接存取,其他類想要訪問需要通過外部類
2、可以直接使用外部類的所有屬性(包括私人屬性)和方法,在某些情況下比較方便
通常一個類只被另外一個類使用,才把它定義為這個類的內部類。
/** * 內部類 */public class Outer { public static void main(String[] args) { Face f = new Face(); //要先有外部類成員,才能new內部類的成員和調用內部類的方法 Face.Nose n = f.new Nose(); n.breath(); Face.Ear e = new Face.Ear(); e.listen(); }}class Face{ String shape; String color; static String skin; class Nose{ String height; void breath(){ System.out.println("breathing..."); //Nose可以訪問shape, color; Face不能訪問height } } static class Ear{ void listen(){ System.out.println("I‘m listening..."); //靜態內部類不可以訪問外部類的普通屬性,shape,color。但是可以訪問外部類的靜態屬性:skin } }}
Java物件導向