java 之 類和對象 筆記

                                   =============類和對象 ======================
 
 類:類是同一類事物的總稱。
對象:現實世界中實實在在存在的事物。
類和對象的關係:類是封裝對象的屬性和行爲的載體,反過來說具有相同屬性和行爲的一類實體稱爲類。如鳥類有鴕鳥、大雁、麻雀等。鴕鳥、大雁、麻雀被稱爲鳥類的實體,即對象。
 
面向對象:對象所共有的功能和屬性進行抽像,成爲了類。客觀事物在人腦中的主觀反映。在程序裏類是創建對象的模板。  
面向對象程序設計的特點:封裝性、繼承性、多態性。

類成員:成員變量(屬性)和成員方法(行爲)。
定義成員方法的格式:權限修飾符 返回值類型 方法名(參數類型 參數名)
               {方法體 return返回值} 成員方法需要返回值時使用關鍵字 return
 
java中的對象 :對現實對象的抽象(獲得有用的,捨棄沒用的)。
      存儲空間中的一塊數據區域,用於存數據。如:人(nama sex age)
       屬性:實例變量(定義在類以內,方法之外)  
            1.默認的初值
            2.實例變量的使用範圍至少是類以內
            3.實例變量調用必須有對象,實例變量和局部變量重名,局部優先。
               
例:
public class Test{
      public static void main(String[] args){
      
      //新建對象stu;stu存的是新建對象stu的地址。stu的專業術語:引用/對象變量/引用變量/實例變量
           Student stu=new Student();        
           stu.name="tom";       //給對象stu的name屬性賦值。
      }}
class Student{              //用類聲明的數據(str)爲引用類型,如:Student str;
 
      //實例變量:定義在方法之外,類以內的,沒有static修飾的變量
      //實例變量會有一個默認的初始值。初始值與變量定義時的類型有關。
      //實例變量(成員變量)--->屬性。可通過新建對象的引用來訪問類的實例變量。如,stu.name;
      String name;     
      int age;
      String sex;
}
實例變量和局部變量的區別:
1,位置:局部變量定義在方法裏面。實例變量定義在類以內方法之外。
2,使用的範圍:局部變量只能在定義他的方法裏面使用,直接調用變量名就可以了。
      實例變量至少可以在定義他的整個類內使用,使用時必須用對象去調用。只有跟對象一起實例變量纔有意義。
3,局部變量使用之前必須初始化。實例變量不需要賦初值,系統會給默認的初值。
 
4,局部變量在同一方法裏不能重名。局部變量和實例變量可以重名,在方法裏採用就近原則。
 
=================方法:=============
包括:
      方法: 
       做什麼:方法的定義  
           修飾符   返回類型   方法名(參數列表) 異常
       怎麼做:方法的實現 {******}          
修飾符(如:public)  返回類型(如:int) 方法名/函數名(參數表--形參)          
如:
      public void eat(String fish){                //eat(),吃的功能。
           //怎麼做.
      }
使用實例方法時也需要用對象去調用。如:stu.eat("fish");
 
======構造方法====== 
 
功能:創建其所屬類型的一個新的對象。(構造方法無返回值類型)
語法格式:
< modifiers修飾符>  <class_name類名>([< argu_list>]) {
          [< statements>]  方法體
} 
舉例:
–class Person {
int age;
Person() { age = 18; }
Person(inti) { age = i; }
void setAge(inti) { age = i; }
–}  
Java語言中,每個類都至少有一個構造方法;
如果類的定義者沒有顯式的定義任何構造方法,系統將自動提供一個默認的構造方法:
–默認構造方法沒有參數
–默認構造方法沒有方法體
Java類中,一旦類的定義者顯式定義了一個或多個構造方法,系統將不在提供默認的構造方法;每個子類的構造方法裏都有一個父類的默認構造方法,即super(),注意:前提是父類沒有顯示的構造方法,當父類有一個或多個顯示構造方法時,子類的構造方法要想調用,必須在方法體第一行加上 super(參數類型)。
 
 
 
方法重載(overloading):編譯時多態。
在一個類的內部,方法名相同形參數不同的方法,對返回類型不要求,這種現象稱之爲重載;
編譯器會自動選擇使用的方法。體現了一個編譯時多態。
好處:對使用者屏蔽因爲參數不同造成方法間的差異。
找方法時如果沒有合適的,採取自動向上擴展原則。
調用時形參之間的區別一定要明確。
    1. 形參的個數不同
    2. 形參的類型不同
    3. 形參的順序不同
    4. 形參的名字相同
 
方法覆蓋(override):運行時多態。
1,發生在父類和子類之間
2,方法名相同,參數相同,返回類型相同
3,子類方法的訪問權限不能更嚴格,只能等於或更加寬鬆。
 
構造方法:
1,沒有返回類型,方法名必須和類同名。
2,構造方法不能手動調用,它只用在創建對象在時候,只出現在new之後。
      只要構造方法被調用運行,就一定有對象產生。
3,在一個對象的生命週期裏,構造方法只能被調用一次。
4,類寫好後一定有構造方法,
      如果程序沒有顯示的提供構造方法,JVM會提供一個默認的構造方法,public classname(){}
      如果程序顯示提供,系統不再提供默認的
5,同一個類的多個構造方法一定重載。
6,創建對象的同時構造方法的代碼塊裏還可以寫需要運行的代碼,還可以給屬性(實例變量)賦值,
      引用類型的屬性賦值就是用new創建對象,然後調用構造方法。如:Student stu=new Student();
用new創建對象時JVM做的三件事:
如:Student stu=new Student();
1,申請空間;(把值放到空間裏,再把空間的地址給引用變量。)----創建父類對象
2,初始化實例變量;沒顯示聲明值的話就用默認值。
3,執行構造方法,
因爲實例變量在創建對象的過程中被初始化,所以使用實例變量前必須創建對象(要用對象去調用),否則實例變量根本不存在
 
=====關鍵字:this=======
1,在普通方法裏,指代當前對象引用(哪個對象調用該方法,this就指向該對象)
2,this不能出現在靜態方法裏。
3,在構造方法裏,this用來指代本類的其他構造方法。在本類構造方法之間互相調用。如:this(形參);
      使用時放在構造方法裏的第一行。
4,不能寫成死循環(不能遞歸調用)
=====關鍵字:super=======
(和this的用法類似)
1,調用父類的構造方法,在子類調用父類的構造方法必須出現在第一句,構造方法第一句可能出現的三種情況(調用父類的構造方法看子類構造方法的第一句)①super();②super(參數)注意傳遞的參數一定是實體,有值的。③this(),先在本類的構造方法間調用,再看調用那個構造方法的第一句是什麼
2,super訪問父類的變量和方法,及super代表父類的對象,super.name;super.setName();
注意:this 和super關鍵字不能同時存在在方法體中。
======參數傳遞========
1,參數相當於局部變量
2,參數傳遞相當於賦值語句
3,基本類型數據傳遞的是本身的值,引用類型數據傳遞的是引用xx(Animal animal)(地址,對象變量本身的值)
 
面向對象的三大特性:
 
一,封裝(Encapsulation):一個系統以合理的粒度出現。
定義:封裝就是將客戶端不應看到的信息包裹起來。使內部執行對外部來看不一種不透明的、是一個黑箱,客戶端不
 
需要內部資源就能達到他的目的。(封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。面向對象
計算始於這個基本概
念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。)
1.事物的內部實現細節隱藏起來
 
2.對外提供一致的公共的接口――間接訪問隱藏數據         3.可維護性  
訪問控制修飾符:public(公開的),protected(受保護的,1,本包內可見;2,其他包的子類可見)
                        default(默認,本包內可見),private(私有的,類內部可見)
訪問控制修飾符   (可以範圍)          (可修飾)下面的類(指外部類)
      private         本類            方法,屬性
      default         本包            類,方法,屬性
      protected     本包+子類                方法,屬性
      public         到處可見          類,方法,屬性
 
1,屬性:隱藏所有屬性,用private。隱藏後屬性只能在類以內訪問 。程序可以根據需要提供get和set
2,方法(函數):該公開的公開,該私有的就私有。(視情況而定)
3,公開方法的功能,隱藏方法的實現細節。
 
二,繼承(inheritance):抽象出不變性。
從一般到特殊的關係,可以設計成繼承
   特點:共性寫在父類裏面,特性寫在子類
所有類的總父類是Object (Object是類的祖先)
父類裏寫的是共性,子類裏寫的是特性。
父類中用private修飾的屬性和方法不能被子類繼承;
但是父類裏的屬性子類都有,如果子類有特殊屬性的話,就要在子類裏定義
且在創建該子類對象的時候初始化屬性(包括父類所有屬性和該子類所有屬性);
 
什麼樣的功能和屬性可以繼承到子類?
對於父類裏的屬性和方法,子類有權訪問的,我們稱爲可以繼承;
 
用new創建子類對象,JVM執行的過程:Dog d=new Dog(); 爲d申請空間。class Dog extends Animal{}    
(1)申請空間;(把值放到空間裏,再把空間的地址給引用變量。)
(2)看本類構造方法的第一句
(3)默認的創建父類對象:
      執行順序:子類(2)--->  父類(2-->3-->4-->5)--->   子類(4-->5),
      新建一個對象空間只申請一次(該空間存放所有父類和子類)。)
(4)初始化本類的實例變量(該類的所有屬性);
(5)執行本類的構造方法,(構造方法只會在創建一個對象的時候被執行一次)
 
(創建是先執行父類的構造方法,在執行子類的構造方法,訪問時先訪問子類自己的特殊屬性和方法再訪問父類的屬
性和方法)
用super調用父類被子類覆蓋的普通方法和遮蓋的屬性
,
指代的是在創建子類對象過程中,由JVM自動創建的那個父類,如:super.方法名()/屬性
 
用super調用父類的構造方法;必須出現在子類構造方法的第一句。如:super(形參);
 
1,在子類的構造方法裏如果沒有指明調用哪一個父類的構造方法(就是子類中沒有super(形參)語句;),
 
      JVM會默認調用父類的無參構造方法,跟本類構造方法的形參沒有關係。
 
2,顯示的寫super,JVM會根據參數調用相應的父類構造方法。
 
3,有this(形參),在本類的構造方法之間調用,看被調用的那個構造方法的第一行。
 
 
 
 三,多態(polymorphism):多態只有方法多態,沒有屬性多態。
用父類類型屏蔽子類之間的差異
 
所有的子類對象都可以當父類對象來用,一個父類型的引用可能指向的是一個子類對象,
如:把狗(對象)看作動物(類型)。Animal a=new Dog();               編譯看前面,運行看後面。
                            (編譯時類型)   (運行時類型)
1,運行時對象不會改變(對象是客觀存在的),如:狗這個對象的屬性和方法是不會改變的。
2,對一個引用,只能調用編譯時類型裏的已知方法。
      如:編譯器知道動物裏已有的屬性和方法,但不知道狗的屬性和方法。
3,運行時會根據運行時類型自動尋找覆蓋過的方法運行。
 
引用  instanceof 類名         
  instanceof是Java的一個二元操作符,和==,>,<是同一類東西。
  由於它是由字母組成的,所以也是Java的保留關鍵字。
  它的作用是測試它左邊的對象是否是它右邊的類的實例,返回boolean類型的數據。
 
//結果爲boolean值,
引用所指向的對象和類名類型是否一致(對象是否屬於類名類型)
類型的轉換:轉換編譯時類型
   Sub  su= (Sub) s;
   子類型的引用向父類型轉換時,不需要強轉
   父類型的引用向子類型轉換時,需要強轉                                                     
     Animal a=new Cat();
     Dog d=(Dog)a;      // 類型轉換異常 
     引用  instanceof  類名 -----> boolean
     引用所指向的對象和類名所代表的類型是否一致   
     a instanceof Animal ----->  true      a instanceof Cat---------->  true    a instanceof Dog----------->false
     Employee e=new Manager();
     e instanceof Employee ------>true
     e instanceof Manager------> true     
     
 屬性沒有多態,屬性只看編譯時類型
 
    
編寫程序的順序:
class 類名{
      private屬性(有什麼)
      無參的構造方法(public類名(){})
      有參的構造方法(作用:給屬性賦值)
      set和get(設置和獲得屬性)
      業務方法(做什麼)
}
 
一,修飾符:static 
      static變量:如:static int index=2;
           類的所有對象共同擁有的一個屬性;可以用類名直接訪問,又稱爲類變量,
           類的所有對象共同擁有的一個變量;類第一次被加載時會初始化靜態變量
(也就是會先執行static修飾的變量);
           跟類創建了多少對象無關;任何對象對靜態變量做的修改,其他對象看到的是修改後的值。
            可以用作計數器,記錄類創建對象的個數, static變量在類加載的時候只會被初始化一次,
      static方法:如:public static void teach(){}
           可以用類名直接去調用,不需要對象所以不能直接訪問(在沒有對象的情況下)實例變量,
在靜態方法裏不能出現this和super,類的所有對象共同擁有的一個方法;跟類創建了多少
 
對象無關。
           在繼承裏,父類的靜態方法只能被子類的靜態方法覆蓋,且覆蓋以後沒有多態
(訪問的是父類的靜態方法);
      static初始化塊:如:class Teacher(){
                                  static int index=4;
                                  static{          //static初始化塊
                                       .........
                                       }
                                  }
      靜態初始化塊:用static修飾類裏面的一個獨立的代碼塊,類第一次被JVM加載的時候執行,只
被執行一次。
      類加載:JVM在第一次使用一個類時,會到classpath所指定的路徑去找這個類所對應的字節碼文件,
           並讀進JVM保存起來,這個過程稱之爲類加載,一個線程一個jvm。
  
      
二,final  (最後的,最終的)final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承
      final類:如:final class Animal{}
           表示該類不能被繼承,意味着不能改變裏面的代碼;
           對虛擬機的正常運行有重要作用的類通常用final修飾,如:String,System,Math ...等類
      final方法:如:public final void sleep(){}       該方法不能被覆蓋(修改),但能被子類訪問。
                      
      
      final變量:如:final (static) int index=4;
                      該變量是常量能被繼承(訪問);
                      final修飾的變量就是常量,通常和static一起連用,來聲明常量;
                      final修飾引用類型數據,指的是引用(地址)不能變,但引用裏的數據不受限制。
                      final修飾的變量,只要在初始化的過程中就可以賦值。
 
                      實例變量:聲明的同時或構造方法裏賦值;
                      靜態變量:聲明的同時或在靜態代碼塊裏賦值;
 
三,abstract
      abstract類:如:abstract class Animal{}
                      抽象類,不能創建對象(如一些父類),但是可以聲明一個抽象類型的引用
                      (可以聲明父類類型子類對象,編譯時利用多態調用抽象方法)。
                      含有抽象方法的類一定是抽象類,但抽象類並不一定要有抽象方法;
                      抽象類一般是用來被繼承的;子類繼承自抽象類,就要實現裏面的抽象方法,
                      如果不想讓子類也是抽象類的話,必須實現父類裏面所有的抽象方法。
                      抽象類有構造方法,有父類,也遵循單繼承的規律。
      
      abstract方法:如:public abstract void sleep();
           抽象方法,只有方法名的定義,沒有實現體(只定義了能做什麼,沒定義怎麼做),不能被調用,
                      用於被子類的方法覆蓋或重新實現。只能放在抽象類中。
                      好處:允許方法的定義和實現分開。
                      public  protected  default  private  static final  abstract
                   可以: public static 
                           private static 
                          public final
                          public static final
                 不可以:abstract final void eat();  
                 private abstract void eat();
                 static abstract void eat();
            abstract不能和final,private,static連用。
 
四,interface:是抽象類的變體,。在接口中,所有方法都是抽象的。如:interface M{
                                       int num=3;
                                       void eat();
                                  }
      理解爲接口是一個特殊的抽象類,所以接口不能創建對象,且接口沒有構造方法,
      但可以聲明一個接口類型的引用(m是接口類型實現類對象,如:M m=new N();)
      接口存在的意義是被子類實現,如果不想讓子類也抽象,
      就要實現接口裏面所有的抽象方法,實現過程中注意訪問權限;
 
      用  implements 關鍵字實現接口,如:class N implements M{
                                                  public void eat(){...}
                                                }
      接口裏面的常量默認都是public static final的;
      接口裏面的方法默認都是public abstract的。
      
      接口本身支持多繼承,繼承了父接口裏功能的定義,如,interface A extends B,C,D{}        //A,B,C,D都是接口;
      類可以同時繼承一個父類和實現接口(或多個接口)。
      如:class AA extends BB implements CC,DD,EE{}//AA,BB      是類,CC,DD,EE是接口;
      作用:1,用接口去實現多繼承,接口是對類的共性進行再次抽象,抽象出類的次要類型。
                 如:蜘蛛俠,擁有人和蜘蛛的屬性,但主要類型是人,次要類型(接口)是蜘蛛,
                 因爲接口是次要類型,所以在類關係裏不佔一個節點,不會破壞類層次關係的樹狀結構,
             2,標準(保證弱耦合):一個接口就是一個標準(裏面的屬性不能改變,只定義了功能,
但沒有被實現),  接口將標準的制定者,標準的實現者以及標準的使用者分離開,
                 降低實現者和使用者的耦合。接口是java裏一種重要的降低耦合的工具;
接口可以屏蔽不同實現類的差異,
                 當底層的實現類更換後,不會對上層的使用者產生影響,體現在參數和返回值。   
                 
                 寫程序時,應該先寫實現者再寫使用者,如:Bank.java是實現者,View.java是使用者,
                 但是有了接口之後,就可以用接口回調的功能;
                 接口回調:先定義接口,然後寫使用者和實現者的順序隨便(一般是先寫使用者,
後寫實現者);利用參數把實現者傳給使用者(即:實現者是使用者的屬性),
使用者利用接口調用實現者相應的功能。
       **接口和抽象類的區別1一個類可以implements多個接口,而只能extends一個抽象類
                       2,一個抽象類可以實現部分的方法,而接口都是抽象的方法和屬性
 
Object是Java裏所有類的直接或間接父類,Object類裏面的所有功能是所有java類共有的
1,JVM調用垃圾回收器回收不用的內存(沒有引用指向的對象)前運行finalize(),給JVM用的方法。
      程序顯示的通知JVM回收沒用的內存(但不一定馬上就回收):System.gc();或    Runtime.getRuntime().gc();
 
2,toString()返回對象的字符串表現形式,打印對象時,虛擬機會自動調用toString獲取對象的字符串表現格式,
      如:System.out.println(str.toString());      ==System.out.println(str);
      如果本類不提供(覆蓋)toString(),那麼使用的是Object類裏的相應方法,打印的就是地址。
      如:public String toString(){
                 return ".....";
           }
           
3,基本類型時“==“判斷變量本身的值是否相等;引用類型時,判斷的是地址是否相等。
      equals判斷的是對象內容是否相等。對於自己創建的類,應該覆蓋Object類的equals()方法;
      否則使用的是Object類裏的equals()方法,比的是地址。
      
      覆蓋方法如下:
      /*****************************************************
      public boolean equals(Object o){  
        if(o==null)  return false;
        if(o==this)  return true;
        if(!(o.getClass()==this.getClass())) return false;
        final Student s=(Student)o;
        return this.name.equals(s.name) && this.age==s.age ;  //比較原則;
      }  
    ******************************************************/
      覆蓋euqals()方法時遵循的原則:
      自反性:a.quals(a);         //true
      對稱性:a.equals(b);<==> b.equals(a);      //true
      傳遞性:a.equals(b);//true         b.equals(c); //true
           --->則:a.equals(c);  //爲true                
      
封裝類(Wrapper class):
OverLoading時,基本類型時採用向上匹配原則,
如果沒有基本類型的話就向包裝類轉換,如果還沒有就讓這個基本類型在包裝類裏也採用向上匹配原則;
 
基本類型-轉換到-->包裝類
boolean----->Boolean
int-------->Integer      //Integer是引用類型,
int-------->Ddouble           //合法,         但Integer------>Double    非法
double------>Double
   ......  ------->   ......
任何類型----->Object
基本數據類型int可以向double自動擴展,但是包裝類型之間不能自動的相互轉換,
基本類型數據--->包裝類型
int i=3;
Integer it=new Integer(i);        //手動轉換;基本類型向包裝類型轉換。
int <----> Integer <----> String
轉換時String類型必須爲全數字字符串。如:"2515"    不能爲:"abc265","aec"...等
String str=”123”; int it=Integer,parseInt(str);把字符串轉換成數字。String str2=it+“”;把數字轉化成字符串
 
==內部類============
定義在其他代碼塊(類體或者方法體)裏的類稱爲內部類;
編譯後每一個內部類都會有自己的獨立的字節碼文件,
文件名:Outer$Inner.class-->內部類也可以有父類和實現接口。也可以有抽象方法。
 
根本位置和修飾符的不同分爲四種:
1,member inner class       成員內部類,當實例方法或變量一樣理解。
      1)定義的位置:類以內,方法之外,沒有靜態修飾符(static)。
      2)本身能定義的屬性和方法:只能定義非靜態的屬性和方法。
      3)能直接訪問的什麼:能訪問外部類的所有靜態和非靜態的屬性或方法。
      4)怎麼創建對象:在外部類內的方法內:Outer.Inner inner=new Outer().new Inner();
            在外部類外的類的方法內:Outer.Inner inner=new Outer().new Inner();或
在Outer類裏提供一個getInner()方法,返回內部類的對象,這樣在外部類外的類的方法內也可以用該成員內部類。
      
2,static inner class 靜態內部類(嵌套內部類),當靜態方法或變量一樣理解。
      static只能修飾內部類,不能修飾外部類。
      1)定義的位置:類以內,方法之外,有靜態修飾符(static)。一般寫在外部類的屬性下面。
      2)本身能定義的屬性和方法:可以定義靜態和非靜態的屬性或方法。
      3)能直接訪問的什麼:只能訪問外部類的靜態屬性和方法。
      4)怎麼創建對象:在外部類內的方法裏: Outer.Inner inner=new Outer.Inner();
                                 在外部類外的類方法裏:   Outer.Inner inner=new Outer.Inner();
3,local inner class        局部內部類           當局部變量一樣理解。
      1)定義的位置:方法裏面的類,前面不能用public或static修飾。
      2)本身能定義的屬性和方法:只能定義非靜態的屬性和方法。
      3)能直接訪問的什麼:能訪問方法內用final修飾的局部變量(不能與該類內的變量名相同)。
                                       能訪問外部類的所有靜態和非靜態的屬性或方法。
      4)怎麼創建對象:只能在方法內創建對象,如:Inner inner=new Inner(); 對象的作用範圍只在方法內。
4,annonymous inner class         匿名內部類                       如:  Teacher tc=new Teacher(){
      1)沒有名字的類,沒有構造方法。是一個特殊的局部內部類,                 public void teach(){...}
             可以實現一個接口,   或者一個類,                                            }
             生命週期裏只能產生一個對象(tc),也就是說只能被一個對象(tc)調用,
      2)除了沒有名字外,看匿名內部類所在的位置,他的定義和訪問將和成員內部類、靜態內部類、局部內部類一樣。
                 一般像局部內部類的定義和訪問比較多。
      3)當試圖創建接口或者抽象類對象的時候,用匿名內部類。
           表示類體的{...}緊跟在抽象實例(接口)之後,表示實現該抽象實例(接口)。
           調用匿名內部類的方法只能用寫類時創建的那個對象(tc)。
作用:1,不破壞訪問權限的情況下,內部類可以使用外部類的私有成員變量和方法。
           2,將接口公開,將實現類(實現公開的接口)作成內部類隱藏起來,強制要求使用者使用接口,強制降低偶合度。
           3,Java通過接口和內部類兩種機制來實現多繼承。在類內部可以建立本類的實例,然後調用本類內的其他方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章