面向對象是相對於面向過程而言的。面向過程注重的是過程,強調的是在完成的這個過程當中的動做。面向對象注重的是對象,只要找到了這個對象,就擁有了這個對象所具備的一切功能。java
好比作飯,若是本身作飯的話,就須要本身準備食材,炊具等等,還要進行烹飪。可是當咱們找到一個餐館,這些事情就都不需本身作了,就等着吃飯就好了。此時餐館就至關於一個對象,咱們只要找到了這個餐館,就擁有了這個餐館具備的一切功能。sql
面向對象是基於面向過程的。面向對象不必定優於面向過程,若是事物相對簡單,適合用面向過程;若是事物比較複雜,適合於面向對象。數據庫
根據一類事物進行抽取,將這一類事物用一個類表示,同時將這一類事物的共有特徵抽取成屬性,將這一類事物的共有行爲抽取成了方法。類是對象的抽取/歸納。經過new關鍵字來產生對應的對象/實例。對象是類的實例化/具體化。數組
好比:人通常都有姓名、性別、年齡等一些特徵,還有睡覺等行爲。咱們就能夠進行以下的操做:安全
public class PersonDemo{ public static void main(String[] args){ Person p = new Person(); p.name = "rose"; p.age = 18; p.gender = '女'; } } calss Person{ String name; int age; char gender; public void sleep(){ System.out.println("sleep !"); } }
對象在內存中的存儲以下圖:網絡
public class PersonDemo{ public static void main(String[] args){ Person p = new Person(); p.name = "翠花"; p.age = 18; p.gender = '女'; changeName(p); System.out.println(p.name); //結果是如花。 } Public void changeName(Person p2){ P2.name = "如花"; } }
注意:對象在傳值的時候傳遞的是地址。上個章節咱們已經強調過。併發
內存調用以下圖:ide
在類內方法外的變量叫成員變量。函數
在方法內的變量叫局部變量。高併發
在定義格式上相同。
成員變量是定義在類內方法外;局部變量是定義在方法或者語句內部。
成員變量做用域整個類;局部變量只能在定義的方法或者語句內部使用。
成員變量存在堆內存中,而且在堆內存中自動的賦予默認值;局部變量是存儲在棧內存中,不會自動給值,須要手動初始化。
成員變量是隨着對象的建立而加載到堆內存中,並獲取默認值,隨着對象的回收而釋放(解析);局部變量在方法或者語句執行的時候建立,隨着方法或者語句的結束而當即移除出棧內存。
在類中與類同名,沒有返回值,也沒有返回值類型的方法,主要是用於建立對象(描述對象建立過程)叫作構造方法,也叫構造函數。
若是一個類沒有手動提供構造函數,那麼JVM在編譯的時候會添加一個無參的構造函數。若是手動添加了構造函數,JVM就不會再提供無參構造函數。
class Person{ public Person(){} }
構造函數在類的對象建立時就運行,一個對象建立後,其構造函數只執行一次,就是建立時執行。父類中必須有一個無參的構造函數,子類中能夠有有參的也能夠有無參的不用上下對應。
public 類名(參數1,參數2,……){ Code; }
1.構造方法沒有返回值類型,也沒有返回值。
2.構造方法能夠重載。
3.構造方法能夠寫return語句,爲了規避風險。
4.構造方法能夠有參數,參數通常是建立對象必須依賴的條件(前提條件)。
5.構造方法能夠存在與類同名的普通函數。可是通常不建議使用。
我將這5個特色簡單記憶爲1個沒有,4個能夠。
任何一個對象建立時,都須要初始化才能使用,因此任何類想要建立實例對象就必須具備構造函數。標識對象建立的開始和結束。
構造函數能夠對對象進行初始化,而且是給與之格式(參數列表)相符合的對象初始化,是具備必定針對性的初始化函數。
this表明當前對象的引用。
注意:在Java中全部的非靜態屬性和非靜態方法都會經過對象來調用的。
this表明當前在使用的對象。
能夠認爲是一個虛擬對象,能夠經過this在本類中調用本類的非靜態方法和非靜態屬性。
this語句表示在本類的構造函數中調用本類的其餘的對應形式的構造函數。
this語句會自動匹配對應形式的構造函數。
this語句必須放在構造函數的第一行。
class Person{ public Person(){} public Person(String name,int age){ this.name = name; this.age = age; } public Person(String name,int age,int gender){ this(name,age); //this語句。調用自己的構造函數。 this.gender = gender; } }
1.引用成員變量。
2.調用類的構造方法。
3.返回對象的值。return this;
沒有名字的對象(匿名對象其實就是定義對象的簡寫格式)。
//正常形式 Car c =new Car(); c.run(); //匿名對象形式: new Car().run();
1.當對象對方法僅進行一次調用的時候,就能夠簡化成匿名對象。
new Person.eat(); new Person.age = 20;
2.匿名對象能夠做爲實際參數進行傳遞。
changeAge(new Person);
在函數或者語句內部用{ }括起來的代碼塊稱之爲局部代碼塊,又叫普通代碼塊。是做用在方法中的代碼塊。
Public static void main(String[] args){ { Int i = 2; System.out.println(i); } //i 變量被釋放。 Int j = 3; System.out.println(j); }
用於限制變量的使用範圍和生命週期,從而提升內存的利用率。
直接在類中定義且沒有加static關鍵字的代碼塊稱爲構造代碼塊,也叫初始化代碼塊。在構造函數執行以前先執行一次。
構造代碼塊在建立對象時被調用,每次建立對象都會被調用,而且構造代碼塊的執行次序優先於類構造方法。
執行順序:(優先級從高到低)靜態代碼塊→main方法→構造代碼塊→構造方法。
{ 構造代碼塊執行語句 }
把多個構造方法的共同代碼放在一塊兒。
構造代碼塊是給全部對象進行統一初始化,而構造函數是給隊形的對象初始化,由於構造函數是能夠多個的,運行哪一個構造函數就會創建相應的對象,但不管創建哪一個對象,都會先執行相同的構造代碼塊。也就是說,構造代碼塊中定義的是不一樣對象共性的初始化內容。
面向對象的特徵有:封裝、繼承、多態 (抽象)。
封裝是面向對象方法的重要原則,就是把對象的屬性和操做(或服務)結合爲一個獨立的總體,並儘量隱藏對象的內部實現細節。封裝是一種信息隱藏技術。
提升了代碼的複用性。
屬性的私有化屬於類的封裝,提升了代碼的安全性。經過將屬性私有化,而後提供對外的公共的訪問方法來設置或者獲取該屬性,能夠在方法中對屬性的設置或者獲取作一系列的限定。
內部類也是封裝的一種體現形式。
提升了複用性、安全性、使代碼結構更加緊密。
1.使屬性私有化---隱藏信息,實現細節。
2.使屬性值更符合要求---能夠對成員進行更精確的控制。
3.提升了代碼的安全性---類內部的結構能夠自由修改
4.良好的封裝可以減小耦合。
若是一些類中含有相同的屬性和方法,那麼能夠將這些相同的屬性和方法提取到一個新的類中,利用extends關鍵字讓原來的類和新的類產生聯繫,而這個關係稱之爲繼承。新產生的類稱之爲父類(超類/基類),原來的類稱之爲子類(派生類)。
父類是子類的通常化,子類是父類的具體化。
注意:Java中支持的使單繼承。一個子類只能有一個父類。一個父類能夠有多個子類。
子類經過繼承父類可使用父類中的一些方法和屬性。
calss a{} class B extends A{//B類繼承了A類 }
1.繼承關係是傳遞的。
2.繼承簡化了人們對事物的認識和描述,能清晰的體現相關類間的層次結構關係。
3.繼承提供了軟件複用功能。
4.繼承經過加強一致性來減小模塊間的接口和界面,大大增長了程序的易維護性。
5.提供了多重繼承機制。經過使用接口機制來實現多重繼承。
1.提升複用性。
2.提升安全性。
3.統一結構。
1.子類擁有父類非private的屬性和方法。
2.子類能夠擁有本身的屬性和方法,即子類能夠對父類進行擴展。
3.子類能夠用本身的方法實現父類的方法。
1.父類變,子類就必須變。
2.繼承破壞了封裝,對於父類而言,它的實現細節對於子類來講都是透明的。
3.繼承是一種強耦合關係。
1.多繼承在代碼的複用性上要優於單繼承,可是存在方法調用的混亂。
class A{ public int m(){ return 2; } } class B { public int m(){ return 1; } } public class C extends A, B{ C c = new C(); int i = c.m(); // 多繼承會產生方法調用的混亂 }
2.單繼承也能夠提升代碼的複用性,能夠避免方法調用的混亂,提升了方法調用的安全性。
權限修飾符用於限定變量或者方法的使用範圍。
修飾符的控制範圍:
|
本類中 |
同包類中 |
子類中 |
其餘類中 |
Public(公共的) |
能夠 |
能夠 |
能夠 |
能夠 |
Protected(受保護的) |
能夠 |
能夠 |
能夠 |
不能夠 |
默認 |
能夠 |
能夠 |
同包子類能夠 |
不能夠 |
Private(私有) |
能夠 |
不能夠 |
不能夠 |
不能夠 |
權限修飾符的控制範圍從定義的位置上看起。
package cn.a; import cn.a.A; public class extends A{ public static void main(String[] args){ B b =new B(); b.m();//m方法使屬於b對象,m方法沒有在對象對應的子類中用。 } }
在建立子類對象的時候,會先建立一個父類對象,而這個父類對象在子類中以super關鍵字的形式存在。super是父類對象的引用。
super表示在子類中表明瞭父類的對象。經過super來調用父類中的方法或者屬性。能夠將super當作一個虛擬對象。
在子類構造函數中經過調用父類對應形式的構造函數。
若是子類構造函數中沒有手動添加,那麼JVM在編譯的時候會自動添加一個無參的super();。
調用super語句的時候,會自動匹配父類中對應形式的構造函數。
若是父類中沒有提供無參構造函數,則默認省略的super語句就不能使用,那麼這個時候子類的構造函數中須要手動添加一個super語句,super語句必須放在子類構造函數的首行。
this語句和super語句不能同時使用,若是子類的構造函數中已經存在來this語句,它會調用自己的其餘含有super語句的的構造函數,來建立父類。
子類的構造函數中必然直接或者簡介的有一個super語句,在建立子類對象的時候必然先建立一個父類對象。
能夠經過this來調用父類中的方法或者屬性。
// 父類 class Pet { String species; int age; public Pet(int age) { this.age = age; } public Pet(String species, int age){ } public void eat() { System.out.println("在吃食~~~"); } } // 經過extends關鍵字產生的聯繫---繼承 // 子類 class Cat extends Pet { public Cat(){ // super語句必須放在構造函數的首行 super(5); } // 方法的重寫/覆蓋 @Override // 註解---這個註解用於標識這個方法是一個重寫的方法 public void eat() { System.out.println("貓在吃土~~~"); } } class Dog extends Pet { public Dog() { // super語句---表示調用了父類的無參構造 // super(); super(5); } public void sleep() { // super 表明一個父類對象---在子類中調用父類中的方法或者屬性 super.eat(); System.out.println("吃飽以後開始睡覺~~~"); } }
1.super.成員變量/super.成員方法;
用來在子類中調用父類的同名成員變量或者方法。
2.super(parameter1,parameter2……);
用在子類的構造器中顯示調用父類的構造器。
1.構造方法。
2.用private修飾的東西,即全部私有的東西。
3.構造代碼塊和靜態代碼塊。
4.默認權限不一樣包的東西。
多態是指容許不一樣類的對象對同一消息作出響應。即同一消息能夠根據發送對象的不一樣而採用多種不一樣的行爲方式。多態主要針對對象的行爲即方法,而不是對象的屬性。
實現多態的技術稱爲動態綁定,是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
下降模塊與模塊之間的依賴性就是解耦。
多態的產生使爲了解耦,消除類型之間的耦合關係。
1.要有繼承。
2.要有重寫。
3.父類引用指向子類對象。
1.可替換性(substitutability)。多態對已經存在代碼具備可替換性。
2.可擴充性(extensibility)。多態對代碼具備可擴充性。
3.接口性(interface-ability)。
4.靈活性(flexibility)。在應用中體現了靈活多向的操做,提升了使用效率。配合反射實現解耦。
5.簡化性(simplictiy)。多態簡化對應用軟件的代碼編寫和修改過程,尤爲在處理大量對象的運算和操做時,這個特色尤其突出和重要。
在編譯時期就要動態綁定的運行過程。例如:方法的重載。
add(1,2) add(1,2,3) //編譯時期就能肯定要使用的方法。
在運行時期才能肯定綁定的運行過程。例如:向上造型、方法的重寫。
繼承是運行時多態的前提。
①向上造型
1)定義
用父類聲明的,用子類來建立實際對象叫向上造型。
子類的對象能夠向上造型爲父類的類型。即父類引用子類對象,這種方式被稱爲向上造型。
使用向上造型聲明的對象可使用父類中的全部,可是隻能使用子類中,父子類共有的東西。
當向上造型建立對象的時候,用父類聲明,用子類建立,父類在聲明的時候就至關於給來這個對象一份提綱;子類建立對象的時候是告訴來對象該怎麼幹。
當用向上造型來建立對象的時候,對象可以幹什麼,看的是父類。行爲應該怎麼幹,看的是子類。
當用向上造型來建立對象的時候,在編譯的時候只檢查兩個類之間是不是繼承關係,而不去具體檢查是用哪一個類來建立的對象,在運行時期纔會檢查是誰來建立的對象。因此,向上造型使運行使多態。
②方法的重寫
當調用方法的時候,調用的是重寫以後的方法。
在編譯的時候只須要檢查這個聲明的類中是否包含指定的方法,在運行的時候才綁定子類中的具體的方法。父類強轉換爲子類會出現ClassCastExcepion(類轉換異常)。
向上造型
重寫和重載
static自己是一個修飾符,能夠修飾變量、方法、內部類、代碼塊。靜態是從類的層面來看的,已經超越了對象。
標記一個方法爲static,意味着這個方法被所在類的全部實例公用,在類裝載時初始化,被全部該類的實例共享,同時意味着:
1.static方法內部不能聲明static變量。
2.Static方法不能被子類重寫爲非static方法。
3.父類的非static方法不能被子類重寫爲static方法。
4.Static代碼塊能夠用static{}來完成,在類被第一次裝載時執行初始化,先於靜態方法和其餘方法的執行。
程序啓動的時候先經過類加載器(ClassLoader)將基本核心類庫(java.long包)加載到方法區,其次是主函數所在的類加載到方法區。
加載主函數所在的類。首先將Java源文件編譯爲class文件,而後class文件經過類加載器(ClassLoader)將class文件加載到方法區當中。將StaticDemo1.class存放到方法區中,將主函數main存放到方法區的靜態區中。
當執行語句Person p1 = new Person(); 時,會將Person類的java源文件編譯成class文件,而後將class文件經過類加載器(ClassLoader)將class文件加載到方法區中。在靜態常量池中開闢空間,將Person.class以及其包含的內容存放在靜態常量池,而後在靜態區中開闢空間,將Person.class中的靜態屬性以及靜態方法存放到靜態區中,並給靜態屬性變量賦予默認值(gender = ‘\u0000’)和方法區空間地址(0x02da)。以上工做完成以後,會在棧內存中聲明一個對象p1。而後執行new Person,在堆內存中開闢空間存儲p1對象的一系列屬性(name,age,gender),並賦予默認值(name = null;age=0;gender = 0x02da;由於gender爲靜態變量因此gender的默認值是方法區中對應靜態變量的空間地址)和堆內存空間地址(0x6f8d),而後將堆空間地址賦值給棧內存中對應的對象。
當執行p1.name = 「張無忌」;時,對象p1會沿着p1對象中存儲的堆內存空間地址找到本身的屬性,給本身的name屬性賦值爲:張無忌,將默認值覆蓋。p1.age = 81;也是如此。
當執行p1.gender = ‘男’;時,對象p1會沿着p1對象中存儲的堆內存空間地址找到本身的屬性gender,而後沿着gender中存儲的方法區空間地址找到方法區中靜態區裏的gender,而後給靜態區裏的gender賦值爲:男。
當執行語句Person p2 = new Person();時,由於全部的類已經加載過了,因此能夠直接進行聲明和初始化操做。棧內存和堆內存中的操做和語句Person p1 = new Person();是同樣的。
當執行語句p2.name = 「趙敏」; p2.age = 18 ; 過程和p1.name = 「張無忌」; p1.age = 81 ; 是同樣的。
當執行p2.gender = ‘女’;時,對象p2會沿着p2對象中存儲的堆空間地址找到堆內存中p2對應的gender屬性,而後在根據gender屬性中存放的地址找到方法區中靜態區裏的gender變量並賦值爲:女,將原來的「男」值替換掉。因爲p1和p2中gender屬性存儲的方法區空間地址是同樣的,因此咱們能夠認爲p1.gender = p2.gender = ‘女’;。
當執行語句p1.eat();時,p1對象會調用方法區中靜態常量池裏Person.class的eat();方法,Person.class會給出eat()方法的地址,而後入棧,在棧內存中開闢空間執行eat();方法,eat();方法中會自動產生this關鍵字表明p1對象,此時this 中存儲的使p1中存儲的堆內存空間地址,而後輸出方法的結果。
static修飾變量那麼這個變量咱們就稱之爲靜態變量,又稱爲成員變量或者類變量。
靜態變量隨着類的加載而加載到了方法區中的靜態區,而且在靜態區中自動賦予了一個默認值。靜態變量先於對象而存在,因此靜態變量能夠經過類名來調用,也能夠經過對象來調用。該類產生的全部的對象實際上存的是該靜態變量在靜態區中的地址,靜態變量是被全部對象所共享的。
例如:System.in; System.out; 都是靜態變量。
1.靜態變量有默認值。
2.靜態變量能夠被類調用,也能夠被對象調用。
3.靜態變量是被全部對象共享的。
4.靜態變量可使用this來調用。
5.靜態變量不能定義到構造代碼塊中,但能夠在構造代碼塊中對靜態變量賦值。
6.靜態變量不能定義到方法中。靜態變量在加載的時候就須要分配空間,而方法在加載的時候不須要空間,在執行的時候才須要內存空間。
注意:實際開發中,static能少用就少用。
1.在語法定義上的區別。靜態變量前要加static關鍵字,而實例變量前則不加。
2.在程序運行時的區別。實例變量屬於某個對象,必須建立對象才能使用。靜態變量則能夠直接使用類名引用。
static修飾方法就叫靜態方法,也叫類方法。
Arrays.sort()、Arrays.toString()、Arrays.copyOf()、System.arraycopy()都是靜態方法。
在類加載的時候加載到了方法區中的靜態區,只是存儲在靜態區,在方法被調用的時候到棧內存中執行。靜態區中的元素不歸屬於某一個對象而是歸屬於類。靜態方法先於對象而存在的,因此靜態方法能夠經過類名來調用,也能夠經過對象來調用。
1.靜態方法中不能定義靜態變量,但能夠對靜態變量賦值。
2.不能在靜態方法中直接調用本類中的非靜態方法。能夠經過建立對象來調用。全部非靜態的方法和變量都須要對象來調用。
3.靜態方法中不能使用this或者super。(主函數是靜態方法)
4.靜態方法能夠重載。
5.靜態方法不能夠重寫。但父子類中能夠出現方法簽名一致的靜態方法,好比:main主函數。若是父子類中出現了兩個方法簽名的一致的方法要麼全是靜態,要麼全是非靜態。
6.靜態方法能夠被繼承。
靜態不屬於對象。而是屬於類。不依賴某個對象而存在,而是依賴於類存在的。類沒有多態,多態針對的是方法
注意:類只加載一次,是在第一次使用的時候才加載到方法區,並且加載到方法區中以後就再也不移除了。
在類中成員的位置用static修飾用{}括起來的代碼塊。
靜態代碼塊針對的是類,因此也能夠叫作類代碼塊。
實際上靜態代碼塊是隨着類的加載而加載到靜態區,在類建立對象或者執行方法以前執行一次,終其一輩子只執行一次。
通常是對類進行初始化。
在這個類第一次被真正使用(第一次建立對象/調用方法)的時候執行一次。若是一個類包含多個靜態代碼塊,則按照書寫順序執行。因爲類只在第一次使用的時候加載,因此靜態代碼塊也只執行一次。
代碼執行順序:先父類後子類,先靜態後動態。(先父子類的靜態,後父子類的動態)靜態優先,父類優先。
代碼是從上到下,從左到右依次編譯執行。
建立子類對象的時候須要先建立父類對象→加載父類→執行父類靜態代碼塊→執行子類代碼塊→父類構造代碼塊→父類構造函數→子類構造代碼塊→子類構造函數
final能夠修飾數據,方法以及類。
當final修飾數據(基本類型和引用類型)的時候,表示這個變量的值不可變,稱之爲常量。終其一輩子只能賦值一次。
在Java中所說的常量每每是指靜態常量。由於實質上只有靜態常量纔是獨有的一個。
System.in/out in和out都是靜態常量。NaN和infinity也是靜態常量。
arr.length length是個常量。
1.常量在定義好以後不可改變,final固定的是棧內存中的數值。
public class Demo { private final int i; public Demo(){ this(5); } public Demo(int i){ this.i = i; } } Demo d = new Demo(5);
2.常量能夠做爲參數傳遞。
3.對引用類型而言,final固定的是其在棧中的地址不可變。
數組在棧內存中存儲的是地址,用final修飾,是不能改變數組的地址,但數組的值能夠改變。對於對象而言,對象的引用不能改變,可是引用的屬性值是能夠進行改變的。
4.成員常量只要是在對象建立完成以前(構造方法/函數執行結束以前)賦初始值便可。
5.靜態成員常量(static final)只要在類加載完成以前給值便可,並且只能在靜態代碼塊中賦值。
final修飾方法的時候,這個方法就是最終方法。
1.最終方法不能夠被重寫,能夠重載,能夠被繼承。
2.靜態方法能夠被final修飾。
final修飾類那麼這個類就是最終類。
1.最終類不能夠被繼承,也不能有匿名內部類形式。
2.現階段最終類的方法不能被重寫。
System 、String是最終類。
abstract class Pet{ public abstract void eat(); } class cat extends pet{ public void eat(){ System.out.println("這隻貓在吃魚……") } }
若是全部的子類中存在了一些名稱一致而細節不一樣的方法的時候,這個時候能夠在父類中聲明該行爲,此時聲明行爲的時候不須要添加方法體,因此此時該方法就造成了抽象方法,使用abstract修飾。
1.抽象方法能夠和抽象方法重載,也能夠和實體方法重載。
2.抽象方法沒有方法體。
1.抽象方法不能夠被static、final、private修飾,由於final和private修飾符修飾的方法都不能夠被重寫;static修飾的方法,先於對象存在,沒有具體對象沒辦法加載。
2.抽象方法可使用默認權限修飾,要求子類必須和父類同包。
3.抽象方法能夠被protected權限修飾,要求要麼同包要麼是子類。
將一些名稱一致可是細節不一樣的行爲提取到父類中定義爲抽象方法,抽象方法所在的類就是抽象類,用abstract來修飾的類。抽象類中,不必定含有抽象方法,可是抽象方法所在的類必定是抽象類。
1.抽象類不能夠在Java中建立對象/實例化。即便沒有抽象方法也沒法建立對象,能夠建立匿名內部類。
2.抽象類有構造方法。抽象類的構造方法能夠私有化,在本類中使用。能夠建立對象,在底層用C語言建立對象。抽象類的構造方法一旦被私有化,就不能被繼承了。
3.抽象類被子類繼承以後,必須重寫其中的抽象方法。子類若是也爲抽象類,能夠不重寫。抽象方法必然會被重寫。
4.抽象類中能夠沒有抽象方法。抽象類中能夠定義一切的屬性和方法。
5.抽象方法不能有方法體,()以後直接以;結尾。
抽象類不能用final修飾。最終類不能夠是抽象類。
限制規定子類必須實現某些方法,但不關注實現細節。
抽象類和普通類的區別就是能夠有抽象方法,不能夠建立對象。
用interface來聲明,全部方法都爲抽象方法那麼咱們就稱之爲接口。經過implements關鍵字讓接口和類產生聯繫,這個過程叫實現。在接口中使用向上造型來建立對象,就是接口的多態。
interface Pet{ void eat(); } public class Mouse implements Pet{ public void eat(){} }
1.接口中方法的abstract關鍵字能夠省略。
2.類用implements來實現一個接口。必須實現這個接口中全部的方法。
3.因爲接口中都是抽象方法,接口不能實例化。
4.接口中沒有構造函數。雖然接口在編譯完成以後會產生class文件,可是接口不是類。
5.接口中能夠定義屬性,這個屬性默認是一個靜態常量。
1.接口中的屬性默認是用public static final 來修飾,修飾符的位置能夠互換。
2.接口中的方法默認用public abstract修飾,並且只能是public修飾的,public能夠省略不寫。在接口的子類中實現接口的方法記得用public修飾。
interface A { void m(); // 默認是public修飾 } public class B implements A { void m(){} // 須要添加修飾符public }
Java中類支持單繼承,多實現。一個類只能繼承一個類,可是一個類能夠實現多個接口。一旦出現了多實現,那就必不可免的會致使方法調用混亂。
interface Pet{ Void eat(); } interface Animal{ Void play(); } public class Mouse implements Pet,Animal{ public void eat(){} public void play(){} }
Java中接口之間是多繼承,而且接口和類之間是多實現的關係,因此就造成了一張繼承關係網,因爲在網狀結構中尋找一個根節點比較困難,爲了提升效率,Java在編譯的時候放棄檢查接口和類之間是否有實現關係。
當類進行強制轉換的時候,JVM在編譯的時候會對兩個類進行檢查,檢查這兩個類之間是否有繼承關係。若是有繼承關係,則編譯的時候會經過,可是運行的時候不必定正確。若是沒有繼承關係,則在編譯的時候直接報錯。
統一告終構。接口能夠做爲模板,配合多態實現解耦,好比:反射。
定義在類或者接口中的類就稱之爲內部類。內部類是封裝的第三種形式。
內部類根據使用的位置和修飾符不一樣分爲:方法內部類、成員內部類、靜態內部類、匿名內部類。
除了靜態內部類,其他的內部類中都不容許定義靜態屬性和靜態方法,可是能夠定義靜態常量。
除了靜態內部類,其他的內部類均可以使用當前外部類的屬性和方法,可是靜態內部類只能使用外部類的靜態成員。
定義在方法中的類叫作方法內部類。
class Outer1{ public void m(){ class Inner1{ public void m(){ System.out.println(「inner1 m」); } } Inner i1 = new Inner1(); i1.m(); System.out.println(「outer1 m」); } }
1.方法內部類在哪定義在哪使用。除了當前的方法,其他地方不能使用。
2.方法內部類優先於當前方法加載。
3.方法內部類不容許使用當前方法的局部變量。可使用當前方法的常量。在JDK1.8中常量不用顯式聲明常量,可是本質上依然是一個常量。
4.方法內部類可使用外部類的一切屬性。
5.方法內部類中能夠定義成員方法、成員屬性和靜態常量,可是不能定義靜態方法和靜態屬性。
爲何要定義方法內部類?
方法內部類是爲了私有本類方法中的參數。內部類能夠繼承能夠實現。
定義在類內方法外的類叫作成員內部類。也就是成員變量的位置。利用外部類對象來建立成員內部類對象。
public class InnerClassDemo { public static void main(String[] args) { new Outer2().new Inner2().m(); //利用外部類對象來建立成員內部類對象 } } class Outer2{ int i=5; class Inner2{ public void m(){ System.out.println("inner2 m"); } } }
1.成員內部類能夠定義普通的方法和屬性,可是依然不能定義靜態方法和靜態屬性。
2.成員內部類能夠定義靜態常量。
3.成員內部類可使用外部類中的一切方法和屬性。
4.成員內部類可使用權限修飾符修飾內部類。
5.成員內部類能夠建立對象。
Java底層集合和映射用的比較多。有一系列對象,而這些對象對外不可見,就能夠用成員內部類。
用static修飾的成員內部類叫作靜態內部類。能夠直接利用外部類來建立靜態內部類的對象。
1.能夠定義一切的屬性和實體方法。
2.靜態內部類只能使用外部類中的靜態屬性和靜態方法。非靜態的屬性和方法不可用。
3.可使用權限修飾符修飾。
沒有名字的內部類叫作匿名內部類。包含成員匿名內部類,方法匿名內部類。
1.匿名內部類本質上是繼承了對應的類或者是實現了對應的接口。
2.只要一個類能夠被繼承,那麼這個類就能夠出現匿名內部類的形式。當利用一個類來建立一個匿名內部類的時候,實際上這個匿名匿名內部類是繼承了這個類。
3.匿名內部類有構造函數,可是不能手動添加構造方法。
當利用匿名內部類來建立對象的時候,要求這個匿名內部類必須實現父類中的全部抽象方法。
Demo demo = new Demo() {//聲明一個匿名內部類 @Override public void m() { } }; // 匿名內部類本質上是實現了這個接口 A a = new A() { }; // B b = new B() { // }; }
4.若是匿名內部類定義到了方法中,此時匿名內部類的使用規則和方法內部類一致。
5.若是匿名內部類定義到了類中,此時匿名內部類的使用規則和成員內部類一致。
定義在類或者接口中的接口叫作內部接口。
類中定義的接口、接口中定義的類或者是接口默認都是用static修飾。
接口必然要被實現,若是內部接口不是靜態的,這個時候就須要一個外部類對象來調用接口,而在聲明類實現這個接口的時候,沒法建立對象,沒法建立對象就沒法實現了。
package cn.tedu.innerclass; public class InnerDemo2 implements Outer1.Inner1 { @SuppressWarnings("unused") public static void main(String[] args) { Outer2.Inner2 oi2 = new Outer2.Inner2(); } } class Outer1 { // 內部接口 // 這個接口默認是用static修飾 interface Inner1 { } } interface Outer2 { // 內部類 // 默認是用static修飾 class Inner2 { } interface Inner3 { } }
聲明包用的package,包的產生是爲了解決同名文件的問題。
聲明格式以下:
package m.n.c
一個Java文件中只容許存在一個package語句,並且這個package語句必須放在整個Java文件的首行。
導入包用的是import。
import java.util.* //表示導入util包下的全部的類而不包括子包下的類。 //*是一個通配符。
java.lang:核心包(核心類庫),在程序啓動的時候就已經加載到了方法區中了,在使用的時候不須要導包。
java.util —— 工具包,存放了一系列簡化操做的工具類。
java.io —— 數據傳輸。
java.nio —— 高併發。
java.net —— 網絡傳輸。
java.math —— 數學運算。
java.sql —— 數據庫。
java.awt —— 圖形用戶界面。(幾乎不用)
java.security —— 數據安全。
java.text —— 格式化。
javax.* —— 擴展包。
org.* —— 第三方廠商和開源社區提供的包。
同包類和java.lang包不用寫導包語句。
注意:包名不能以java,javax,org開頭
以上爲我的學習整理的筆記和心得,於你們分享,但願你們多批評斧正。
上一篇:JAVA基礎知識