整體上是封裝、繼承、多態、抽象。
首先面向對象是一種思想。在java中萬事萬物皆對象。類是對相同事物的一種抽象、是不可見的,對象具體的、可見的。由對象到類的過程是抽象的過程,由類到對象的過程是實例化的過程。面向對象的三大特征分別是封裝、繼承和多態。
封裝隱藏了類的內部實現機制,對外界而言它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。例如在屬性的修飾符上我們往往用的private私有的,這樣其它類要想訪問就通過get和set方法。因此封裝可以程序員按照既定的方式調用方法,不必關心方法的內部實現,便于使用; 便于修改,增強 代碼的可維護性。
繼承在本質上是特殊~一般的關系,即常說的is-a關系。子類繼承父類,表明子類是一種特殊的父類,并且具有父類所不具有的一些屬性或方法。比如從貓類、狗類中可以抽象出一個動物類,具有和貓、狗、虎類的共同特性(吃、跑、叫等)。通過extends關鍵字來實現繼承。Java中的繼承是單繼承,即一個子類只允許有一個父類。
Java多態是指的是首先兩個類有繼承關系,其次子類重寫了父類的方法,最后父類引用指向子類對象。如Animal a=new Dog();這行代碼就體現了多態。
Java中的多態靠的是父類或接口定義的引用變量可以指向子類或具體實現類的實例對象,而程 序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存 里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。
名字與類名相同;
沒有返回值,但不能用void聲明構造函數;
生成類的對象時自動執行,無需調用。
構造器不能被繼承,因此不能被重寫,但可以被重載。
super可以理解為是指向自己超(父)類對象的一個指針,而這個超類指的是離自己最近的一 個父類。
super也有三種用法:
1.普通的直接引用
與this類似,super相當于是指向當前對象的父類的引用,這樣就可以用super.xxx來引用父類的成員。
2.子類中的成員變量或方法與父類中的成員變量或方法同名時,用super進行區分
class Person{?
? ? protected String name;?
? ? public Person(String name){?
? ? ? ? this.name = name;?
? ? }?
}?
class StudentextendsPerson{?
? ? private String name;?
? ? publicStudent(String name, String name1){?
? ? ? ? super(name);?
? ? ? ? this.name = name1;?
? ? }?
? ? public void getInfo(){?
? ? ? ? System.out.println(this.name);?
? ? ? ? System.out.println(super.name);?
? ? }?
}?
public class Test{?
? ? public static void main(String[] args){?
? ? ? ? Student s1 = new Student("Father", "Child");?
? ? ? ? s1.getInfo();?
? ? }?
}
3.引用父類構造函數
super(參數):調用父類中的某一個構造函數(應該為構造函數中的第一條語句)。
this(參數):調用本類中另一種形式的構造函數(應該為構造函數中的第一條語句)。
super:它引用當前對象的直接父類中的成員(用來訪問直接父類中被隱藏的父類中成員
數據或函數,基類與派生類中有相同成員定義時如:super.變量名 super.成員函數據名 (實參)
this:它代表當前對象名(在程序中易產生二義性之處,應使用this來指明當前對象;如果函數的形參與類中的成員數據同名,這時需用this來指明成員變量名)
super()和this()區別是
[1]super()在子類中調用父類的構造方法,this()在本類內調用本類的其它構造方法。
[2]super()和this()均需放在構造方法內第一行。盡管可以用this調用一個構造器,但卻不能調用兩個。
[3]this和super不能同時出現在一個構造函數里面,因為this必然會調用其它的構造函數,其它的構造函數必然也會有super語句的存在,所以在同一個構造函數里面有相同的語 句,就失去了語句的意義,編譯器也不會通過。
[4]this()和super()都指的是對象,所以,均不可以在static環境中使用。包括:static變
量,static方法,static語句塊。從本質上講,this是一個指向本對象的指針, 然而super是一個Java關鍵字。
方法的重載和重寫本質都是實現多態的方式,區別在于前者實現的是編譯時的多態性,而后者實現的是運行時的多態。
方法重載的規則:
1)方法名一致,
2)參數列表不同(參數順序不同或者參數類型不同或者參數個數不同)。
3)重載與方法的返回值無關,這個很關鍵。
方法重寫的規則:
1)參數列表和返回值類型必須完全與父類的方法一致
2)構造方法不能被重寫,聲明為 final 的方法不能被重寫,聲明為 static 的方法不能被重寫,但是能夠被再次聲明。
3)訪問權限不能比父類中被重寫的方法的訪問權限更低。
4)重寫的方法能夠拋出任何檢查異常(編譯時異常),但是重寫的方法不能拋出比被重寫方法聲明的更廣泛的運行時異常。
1)接口中的所有方法都是抽象的,而抽象類可以有抽象方法,也可以有實例方法。
2)類需要繼承,接口需要實現。一個類可以實現多個接口,但只能繼承一個父類但接口卻可以繼承多接口。
3)接口與實現它的類不構成繼承體系,即接口不是類體系的一部分。因此,不相關的類也可以實現相同的接口,而抽象類是屬于類的繼承體系,并且一般位于類體系的頂層。
接口可以繼承接口。抽象類可以實現(implements)接口,抽象類可繼承具體類,但前提是具體類必須有明確的構造函數。
值傳遞是指在調用函數時將實際參數復制一份到函數中,這樣的話如果函數對其傳遞過來的形式參數進行修改,將不會影響到實際參數。
引用傳遞是指在調用函數時將對象的地址直接傳遞到函數中,如果在對形式參數進行修改,將影響到實際參數的值。
equals 和== 最大的區別是一個是方法一個是運算符。
1)基本類型中,==比較的是數值是否相等。equals方法是不能用于基本數據類型數據比較的,因為基本數據類型壓根就沒有方法。
2)引用類型中,==比較的是對象的地址值是否相等。equals方法比較的是引用類型的變量所指向的對象的地址是否相等。應為String這個類重寫了equals方法,比較的是字符串的內容。
hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實際上是返回一個int整數。這個哈希碼 的作用是確定該對象在哈希表中的索引位置。hashCode() 定義在JDK的Object.java中,這就 意味著Java中的任何類都包含有hashCode()函數。
在Java中,每個對象都可以調用自己的hashCode方法得到自己的哈希值(hashCode),相當于對象的指紋信息,通常說世界上沒有完全一樣的指紋,但是在Java中沒有這么絕對,我們依然可以用hashCode值來做一些提前的判斷。
1)如果兩個對象的hashCode值不一樣,那么他們肯定是不同的兩個對象;
2)如果兩個對象的hashCode值一樣,也不代表就是同一個對象;
3)如果兩個對象的equals方法相等,那么他們的hashCode值一定相等。
在Java的一些集合類的實現中,在比較兩個對象的值是否相等的時候,會根據上面的基本原則,先調用對象的hashCode值來進行比較,如果hashCode值不一樣,就可以認定這是兩個不一樣的數據,如果hashCode值相同,我們會進一步調用equals()方法進行內容的比較。
equals 方法是用來比較對象大小是否相等的方法,hashcode 方法是用來判斷每個對象 hash 值的一種方法。如果只重寫 equals 方法而不重寫 hashcode 方法,很可能會造成兩個不同的對象,它們的 hashcode 也相等,造成沖突。
例如:String str1 = "通話"; String str2 = "重地";
它們兩個的 hashcode 相等,但是 equals 可不相等。
不對,如果兩個對象x和y滿足x.equals(y) == true,它們的哈希碼(hash code)應當相同。
Java對于eqauls方法和hashCode方法是這樣規定的:
(1)如果兩個對象相同(equals方法返回true),那么它們的hashCode值一定要相同;
(2)如果兩個對象的hashCode相同,它們并不一定相同。
當然,你未必要按照要求去做,但是如果你違背了上述原則就會發現在使用容器時,相同的對 象可以出現在Set集合中,同時增加新元素的效率會大大下降(對于使用哈希存儲的系統,如 果哈希碼頻繁的沖突將會造成存取性能急劇下降)。
都不能。
1)抽象方法需要子類重寫,而靜態的方法是無法被重寫的,因此二者是矛盾的。
2)本地方法是由本地代碼(如 C++ 代碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。
3)synchronized 和方法的實現細節有關,抽象方法不涉及實現細節,因此也是相互矛盾的。
修飾類:當用final修飾一個類時,表明這個類不能被繼承。正如String類是不能被繼承的。final類中的成員變量可以根據需要設為final,但是要注意final類中的所有成員方法都會被隱式地指定為final方法。
修飾方法:使用final修飾方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現版本中,會將final方法轉為內嵌調用。但是如果方法過于龐大,可能看不到內嵌調用帶來的任何性能提升。在最近的Java版本中,不需要使用final方法進行這些優化了。因此,只有在想明確禁止該方法在子類中被覆蓋的情況下才將方法設置為final。(注:一個類中的private方法會隱式地被指定為final方法)
修飾變量:對于被final修飾的變量,如果是基本數據類型的變量,則其數值一旦在初始化之后便不能更改;如果是引用類型的變量,則在對其初始化之后便不能再讓其指向另一個對象。雖然不能再指向其他對象,但是它指向的對象的內容是可變的。
public class Demo1 {
????public static void main(String[] args) ?{
????????MyClass myClass1 = new MyClass();
????????MyClass myClass2 = new MyClass();
????????System.out.println(myClass1.i);
????????System.out.println(myClass2.i);
????????System.out.println(myClass1.j);
????????System.out.println(myClass2.j); ?
????}
}
class MyClass {
????public final double i = Math.random();
????public static double j = Math.random();
}
運行結果:
0.3222977275463088
0.2565532218939688
0.36856868882926397
0.36856868882926397
每次打印的兩個j值都是一樣的,而i的值卻是不同的。從這里就可以知道final和static變量的區別了。static屬于類級別的不可變,而final是對象級別的不可變。
1)final:用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,被其修飾的類不可繼承。
2)finally:異常處理語句結構的一部分,表示總是執行。
3)finalize:Object 類的一個方法,當java對象沒有更多的引用指向的時候,系統會自動的由垃圾回收器來負責調用此方法進行回收前的準備工作和垃圾回收。
靜態變量: 靜態變量由于不屬于任何實例對象,屬于類的,所以在內存中只會有一份,在類的 加載過程中,JVM只為靜態變量分配一次內存空間。
實例變量: 每次創建對象,都會為每個對象分配成員變量內存空間,實例變量是屬于實例對象 的,在內存中,創建幾次對象,就有幾份成員變量。
靜態方法和實例方法的區別主要體現在兩個方面:
在外部調用靜態方法時,可以使用"類名.方法名"的方式,也可以使用"對象名.方法名"的 方式。而實例方法只有后面這種方式。也就是說,調用靜態方法可以無需創建對象。
靜態方法在訪問本類的成員時,只允許訪問靜態成員(即靜態成員變量和靜態方法), 而不允許訪問實例成員變量和實例方法;實例方法則無此限制。
class A{
static{
System.out.print("1");
}
public A(){
System.out.print("2");
}
}
class B extends A{
static{
System.out.print("a");
}
public B(){
System.out.print("b");
}
}
public class Hello{
public static void main(String[] ars){
A ab = new B(); //執行到此處,結果: 1a2b
ab = new B(); //執行到此處,結果: 1a2b2b
}
}?
輸出結果為 1a2b2b;修飾符 | 當前類 | 同包 | 子類 | 其它包 |
---|---|---|---|---|
public | 是 | 是 | 是 | 是 |
protected | 是 | 是 | 是 | 否 |
默認(缺省) | 是 | 是 | 否 | 否 |
private | 是 | 否 | 否 | 否 |
類的成員不寫訪問修飾時默認為default。默認對于同一個包中的其他類相當于公開 (public),對于不是同一個包中的其他類相當于私有(private)。受保護(protected)對 子類相當于公開,對不是同一包中的沒有父子關系的類相當于私有。Java中,外部類的修飾符 只能是public或默認,類的成員(包括內部類)的修飾符可以是以上四種。
goto 是Java中的保留字,在目前版本的Java中沒有使用。(根據James Gosling(Java之 父)編寫的《The Java Programming Language》一書的附錄中給出了一個Java關鍵字列 表,其中有goto和const,但是這兩個是目前無法使用的關鍵字,因此有些地方將其稱之為保 留字,其實保留字這個詞應該有更廣泛的意義,因為熟悉C語言的程序員都知道,在系統類庫 中使用過的有特殊意義的單詞或單詞的組合都被視為保留字)
由于 Java 不支持多繼承,而有可能某個類或對象要使用分別在幾個類或對象里面的方法或屬性,現有的單繼承機制就不能滿足要求。與繼承相比,接口有更高的靈活性,因為接口中沒有任何實現代碼。當一個類實現了接口以后,該類要實現接口里面所有的方法和屬性,并且接口里面的屬性在默認狀態下面都是public static,所有方法默認情況下是 public.一個類可以實現多個接口。