/* 內(nèi)部類: 1.在類中定義的類我們稱之為內(nèi)部類,它是外部類的一個成員。 2.內(nèi)部類可以直接訪問外部類的成員,但是外部類不能直接的去調(diào)用外部類的成員、 其實內(nèi)部類調(diào)用外部類的成員的時候.其實是使用到了:類名.this.變量名 來訪問外部類的成員。 3.在內(nèi)部類中的方法可以使用this引用調(diào)用這個方法的內(nèi)部類對象. */ class Outer { String name = "張三"; public void run() { System.out.println("Outer is Running"); } public void show() { System.out.println("My name is Outer"); System.out.println(new Inner().age); } class Inner { int age = 19; public void run() { System.out.println("Inner is Running"); } public void eat() { this.run(); //this.代表方法所調(diào)用的對象.它的對象是inner 所以輸出的是inner show(); //因為創(chuàng)建內(nèi)部類的時候.外部類的對象已經(jīng)創(chuàng)建了. 如果虛擬機在內(nèi)部類中找不到.它會到外部類去找這個show()對象. System.out.println(Outer.this.name); //其實同等于:Outer.this.name //類名.name System.out.println("Nnner is Eat"); } } } class Demo { public static void main(String[] args) { Outer.Inner inner = new Outer().new Inner(); //類型要一致! inner.run(); inner.eat(); } } /* 可以在方法中定義內(nèi)部類? System.out.println(age);為什么會訪問不了呢.編譯出錯/ 其實:當(dāng)我們在外部類調(diào)用A對象的時候.run()方法由于age是存儲在棧內(nèi)存的臨時變量中的. 當(dāng)我們對象調(diào)用完畢過后呢. 有可能是會被釋放調(diào)的.而當(dāng)你再次調(diào)用的時候 age 的時候呢.由于虛擬機可能會被釋放.所以調(diào)用不了. 那么:虛擬機認(rèn)為你這樣做是編譯錯誤的! */ class A { String name = "小細" ; public void run() { int age = 19; class B { public void run() { String name = "王五"; System.out.println("my name is B"); //System.out.println(age); System.out.println(A.this.name); //通過類名.this.屬性名訪問外部類的屬性. } } new B().run(); } } class Demo { public static void main(String[] args) { A a = new A(); a.run(); } } /* 匿名內(nèi)部類: */ class Fruit { public void qupi() { } } class Person { public void eat(Fruit f) { f.qupi(); System.out.println("吃完啦??!"); } } class Demo { public static void main(String[] args) { Person p = new Person(); p.eat(new Fruit(){ public void qupi() { System.out.println("Apple把皮弄開!"); } } ); } } /* static修飾的靜態(tài)內(nèi)部類: 1.靜態(tài)的內(nèi)部類可以聲明非靜態(tài)的屬性和方法. 但是靜態(tài)的內(nèi)部類是不能訪問外部類非靜態(tài)的方法.因為外部類的屬性需要創(chuàng)建對象才能調(diào)用. 你內(nèi)部類是不需要創(chuàng)建對象的.所以調(diào)用不了。 2.靜態(tài)的內(nèi)部類不能訪問非靜態(tài)的屬性. */ class Outer { static String name = "kudy"; String ID = "888"; static class Inner { int age = 19; public void run() { System.out.println(age); System.out.println("Inner is happy"); System.out.println(Outer.name); //因為是不需要創(chuàng)建對象的.所以可以使用Outer.name訪問外部的靜態(tài)的方法。 // System.out.println(Outer.ID); } } } class Demo { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); //靜態(tài)的內(nèi)部類一定要靜態(tài)的去創(chuàng)建! //System.out.println(inner.age); inner.run(); } } /* 類的繼承 1.使用extends關(guān)鍵字來聲明類的關(guān)系 2.子類會自動繼承父類的屬性與方法 */ class Person { String name ; public void run() { System.out.println("Person is Running"); } } class Man extends Person { public void toLike() { System.out.println(name +"運動"); //默認(rèn)會添加上this的 } } class Demo { public static void main(String[] args) { Man man = new Man(); man.name = "小細"; man.run(); man.toLike(); } } /* 類的繼承是為了實現(xiàn)代碼的復(fù)用性,如果有多個類具有相同的方法.我們應(yīng)該盡量把她抽出一個類來 */ class Person { String name ; int age; public void eat() { System.out.println(name+"吃飯"+",年齡為:"+age); //this.name this.age } public void run() { System.out.println("需要運動"); } } class Student extends Person { public void eat() { System.out.println("吃一口飯"); super.eat(); //調(diào)用父類的方法、。 System.out.println("看一下作業(yè)"); } } class Teacher extends Person { public void eat() { System.out.println("抽一根"); super.eat(); System.out.println("再來一根"); } } class Demo { public static void main(String[] args) { Student student = new Student(); student.name = "小細"; student.age = 19; student.eat(); student.run(); } } /* 父類型的引用指向子類型的對象.也就是想上類型轉(zhuǎn)換.不需要強制轉(zhuǎn)換 強制轉(zhuǎn)換的要求: 父類型的引用指向子類型的對象。 3.把父類當(dāng)做子類來使用是不行的,因為子類有的.父類型不一定有 4.當(dāng)做子類當(dāng)做父類來用時,只能使用父類型所擁有的方法。 如果調(diào)用子類擁有的方法.編譯器會報錯!所以需要強制轉(zhuǎn)換.但在強制轉(zhuǎn)換的前提下我們要知道父類型的引用是否是指向了子類型的對象 強制轉(zhuǎn)換之前需要判斷一下. 注意: 1.當(dāng)你父類型的引用指向子類型的對象的時候.你必須要清楚的就是:你訪問的屬性是會是父類的.而不是子類的. 因為java在屬性方法是做了靜態(tài)的綁定.誰是我的類型.我就去誰的類型去找.而方法就剛好相反. 方法就是:誰指向誰.我就調(diào)用誰的方法.。 因為是做了動態(tài)的綁定。 */ class Typist { String name = "小細"; public void type() { System.out.println("typeing"); } } class Coder extends Typist { String name = "王五"; public void type() { System.out.println("tepeing slowly!!!"); } public void code() { System.out.println("Codeing"); } } class Demo { public static void main(String[] args) { //向上類型轉(zhuǎn)換: 父類型的引用指向子類型的對象. Typist typist = new Coder(); //typist.type(); 因為你是指向了子類型的引用.所以java做了動態(tài)綁定.也就是說你綁定了一個子類型的方法。 System.out.println(typist.name); /* 為什么輸出小細呢.因為java在檢查的時候.屬性是不做動態(tài)綁定的.也就是說.類型是誰.他就會找類型里面的屬性. */ /* Code code = new Typist(); 子類型的引用不能指向父類的對象.因為子類有的.父類型不一定有. */ Coder coder; if(typist instanceof Coder) //父類型的引用指向子類型的對象才可以搶走轉(zhuǎn)換! { coder = (Coder)typist; //強制轉(zhuǎn)換成子類 System.out.println(coder.name); } } } /* 因為java的屬性在父類型的引用指向子類型的情況是做了靜態(tài)的綁定的.所以我們可以這么做! */ class Person { private String name = "無名氏"; public String getName() { return name; } public void eat() { System.out.println("eating"); } } class A extends Person { private String name = "小細"; public String getName() { return name; } } class B extends Person { String name = "kudy"; } class Demo { public static void main(String[] args) { Person p = new A(); /* 因為java的父類型的引用指向子類型的對象的時候.方法使用了動態(tài).而屬性只使用了靜態(tài).也就是說:類型是那個.屬性就是從 那里去找 */ System.out.println(p.getName());//這樣就是調(diào)用了子類型的屬性啦~~ } } /* 什么情況下使用子類當(dāng)做父類來使用 匿名內(nèi)部類:new一個父類對象,后面跟一個花括號,這時不需要創(chuàng)建父類的實例 */ class Person { String name = "無名氏"; public void eat() { //每個人的愛好不同! } } class Restaurant { public void run(Person p) { p.eat(); } } class Chinese extends Person { public void eat() { String name = "中國人"; //在方法里面是動態(tài)調(diào)用的哦。 System.out.println(name+"我是拿筷子吃的!"); } } class American extends Person { public void eat() { String name = "美國人"; System.out.println(name+"我只吃漢堡包!"); } } class Demo { public static void main(String[] args) { Restaurant r = new Restaurant(); //r.run(new American()); r.run(new Chinese()); /* 內(nèi)部類: class JB extends Person { public void eat() { System.out.println("我是吃垃圾的!"); } } r.run(new JB()); */ r.run(getIndia()); } static Person getIndia() { String name = "印度菜"; Person p = new Person(){ //我創(chuàng)建了一個子類.子類里面有eat方法重寫啦.之后呢.再把這個重寫好的對象返回來.也就是說:父類型的引用指向子類型的對象 public void eat() { System.out.println(this.name+"印度菜"); } }; return p; } } class A { String name = "小三"; public String getName() { return name; } public void run() { System.out.println(name); } } class B extends A { private String name = "小四"; public String getName() { return name; } public void run() { System.out.println(name); } public void show() { System.out.println("我是子類!"); } } class Demo { public static void main(String[] args) { A a = new B(); //父類型的引用指向子類型的對象. 就可以使用子類型與父類型所共同擁有的方法.但是子類出來的就不行。 // a.show(); /* System.out.println(a.name); 如果這樣寫出來是小三,而不是小四,但是在方法里面輸出來的就是小四.因為她的屬性在方法里面運行啦.所以是動態(tài)的. 而你單獨如果想輸出它的屬性的話,它是根據(jù)了靜態(tài)綁定來進行操作.也就是輸出了類型里面屬性的內(nèi)容! 那方法就是: 給所有的變量私有化.給他開一個public方法.返回屬性??!因為方法是可以轉(zhuǎn)換為動態(tài)的. 有的人可能會問?不相同可以嗎? 如果不相同的話.前面已經(jīng)說過: 就是子類型所特有的.你父類型是不可以調(diào)用.除非需要強制轉(zhuǎn)換! */ String name = a.getName(); //這時候方法已經(jīng)給重寫 System.out.println(name); //輸出的會是小四 } } /* 對象的比較: 對象的比較不能使用 == 這樣比較的是比較地址. 應(yīng)該用equals方法 因為所有的類都是默認(rèn)的繼承與Object! 我們可以重寫它里面的equals比較方法。 */ class Person { private String name ; private int age ; public Person(String name ,int age) { this.name = name ; this.age = age ; } @Override //告訴編譯器我重寫父類型的方法! 大寫的O //重寫父類的方法! public boolean equals(Object obj) { if(this == obj) return true; if(obj instanceof Person) //如果你父類型的引用是指向了子類型的對象的.那么就判斷. { //因為是按照了父類型的引用是指向了子類型的對象.首先我們要判斷一下.強制類型轉(zhuǎn)換.要不然我們是調(diào)用不了子類型的內(nèi)容 Person p =(Person)obj; if(this.name.equals(p.name)&&this.age == age) return true; } return false; } } class Demo { public static void main(String[] args) { Person p1 = new Person("張三",19); //p1就是當(dāng)前對象! Person p2 = new Person("張三",19); System.out.println(p1.equals(p2)); } } class Person { String name ; public void eat() { } } class Restaurant { public void show(Person p) { p.eat(); } } class Chinese extends Person { String name = "中國人"; public void eat() { System.out.println(name+"我吃中國菜!"); } } class Test { public static void main(String[] args) { Restaurant r = new Restaurant(); r.show(new Chinese()); /* 匿名內(nèi)部類的第一種用法! */ r.show(new Person(){ public void eat() { System.out.println("日本人吃日本菜!"); } } ); r.show(getUSA()); } public static Person getUSA() { Person p = new Person(){ public void eat() { String name = "美國人"; System.out.println(name+"吃美國菜!"); } }; return p; } }
使用Java的文檔注釋
文檔注釋以“/**”開始,以“*/”標(biāo)志結(jié)束,相應(yīng)的信息和批注所對應(yīng)的位置很重要! 類的說明應(yīng)在類定義之前,方法的說明應(yīng)在方法的定義之前。
批注參數(shù)來標(biāo)記一些特殊的屬性及其相應(yīng)的說明 。
@author<作者姓名>
@version<版本信息>
@param<參數(shù)名稱><參數(shù)說明>
@return<返回值說明>
生成文檔的命令
javadoc -d Engineer -version -author Engineer.java
心得:
我要向前沖,想前沖。