轉 ---java面向對象基礎知識總結


面向過程與面向對象的區別:

面向對象,將跟對象有關的功能都封裝在其內

面向對象三大特征:封裝,繼承,多態

找對象,創建對象,使用對象,並維護對象之間的關系

類:對現實中事物的描述

對象:就是實實在在 存在的事物

映射到java中,描述就是class定義的類

具體對象就是對應java在堆內存中new建立的實體

類與對象:

設計圖紙就是類,里面包含對象的描述:比如說車的顏色,輪胎數,發動機....

Note:對象建立的時候,屬性值都會先置為null,顯式初始化后才會變成具體的值

 

成員變量VS局部變量

作用范圍:    

成員變量作用於整個類中;

局部變量作用於函數或者語句中;

在內存中的位置:

成員變量在堆內存中,由於對象的存在,才在內存中存在;

局部變量在棧內存中;

局部變量必須初始化,否則不能運行;

成員變量有默認初始化值,因此可以不初始化;

當成員變量和局部變量名稱一致時,默認使用局部變量

 

本類中可以創建本類對象(一般不用);

匿名對象:沒有定義名稱的對象

如下圖,左邊是有名稱的對象,右邊是匿名對象

匿名對象的傳值調用:調用結束后,在堆內存新生成的對象成為垃圾(無指向),因此過一段時間就會被垃圾回收機制回收.

封裝:隱藏對象的屬性和實現細節,僅僅提供公共訪問方式;

關鍵字:private 權限修飾符,只在本類中有效

私有只是封裝的一種表現形式

一般情況下,把屬性都隱藏,提供公共訪問方式訪問;

對外提供訪問屬性的方式(set&get方法),是因為在訪問方式中可以加入邏輯判斷等語句;

對訪問的數據進行操作,提高代碼的健壯性

class Person

{

int age;

public void setAge(int a)//一個屬性一般由兩個方法來訪問(設置和獲取)

{

if(a >0 && a <130)

age =a;

else

System.out.println("Illegal age!");

}

public int getAge()

{

return age;

}

}

 

構造函數:函數名和類名一致,不能用return

對象一建立就會調用構造函數,可以用於對特定對象進行初始化;

若類中沒有定義構造函數,系統會默認加入一個空參數的構造函數;

構造函數也可以私有化,私有化后不能使用該函數創建對象

如果所有構造函數都私有化,那么就不能創建對象

一般方法是對象調用才運行,可以被調用多次;

構造代碼塊:給所有對象的共性進行初始化,對象一建立就運行,優先於構造函數執行

{

System.out.println();//沒有函數名

}

 

this:代表當前調用對象(當變量前面加了this,該變量可以認為是成員變量)

當本類功能內部需要使用本類對象時,都用this來表示

class Person

{

private String name;

//同名變量區分

Person(String name)

{

this.name(成員變量) = name(局部變量);

}

//構造函數調用;注意,構造函數不能互相調用,否則將進入死循環

Person(String name,int age)

{

this(name);//只能放在第一行,因為初始化要先執行;再次初始化

this.age = age;

}

}

static:靜態,修飾成員(包括變量和方法,不能修飾局部),表示共性數據

可以被類名調用:類名.靜態成員

被所有對象共享,只占一塊內存(方法區,共享區,數據區)

隨着類的加載而加載,隨着類的消失而消失,生命周期最長

優先於對象存在

被所有對象所共享

可以直接被類名調用(可以不創建對象)

String name;//成員變量,實例變量,隨着對象的建立而存在

static String country = "CN";//靜態變量,類變量

靜態變量和成員變量的區別

存放位置:

實例變量隨着對象的建立存在於堆內存中,

類變量隨着類的加載存在於方法區中

生命周期:

實例變量隨着對象消失而消失

類變量隨着類消失而消失

 

使用注意事項:

靜態方法只能訪問靜態成員

靜態方法中不可以定義this,super關鍵字(因為靜態有限於對象存在)

主函數是靜態的,作為程序入口,可以被jvm調用

利:    對共享數據進行單獨空間存儲,節省空間.

可以直接被類名調用

弊:    生命周期過長,訪問出現局限性(只能訪問靜態)

public static void main(String[] args)解析:

/*

public:代表這該函數訪問權限最大

static:代表主函數隨着類的加載就已經存在

void:沒有返回值

main:特殊單詞,可以被jvm識別

String[] args:參數是一個數組,該數組中的元素是字符串

*/

主函數可以重載,但是jvm只識別main(String[] args);

 

javac 命令 啟動編譯器

java 命令 啟動jvm,所以可以在運行命令java *.class后面添加args參數

class MainDemo

{

public static void main(String[] args)

{

 

}

}

 

靜態變量:當對象中出現共享數據時

靜態函數: 當功能內部沒有訪問到非靜態數據時

若編譯時,當前調用的class不存在時,會先去當前目錄下找相應的java文件,如果有,則會直接編譯,生成class文件

 

靜態代碼塊:隨着類的加載而執行,只執行一次,優先於主函數

用於給類進行初始化

構造代碼塊會執行多次;

運行順序:靜態代碼塊,構造代碼塊,構造函數

class StaticDemo

{

static

{

執行語句

}

void show(){}

}

StaticDemo.show();//加載

StaticDemo s1 = new StaticDemo;//加載

StaticDemo s1 = null;//未加載

 

一個對象的建立過程

Person p= new Person("zhangsan",20);

1.找到Person.class文件並加載到內存中

2.執行static代碼塊

3.在堆內存中開辟空間,分配內存地址(main函數開始)

4.在堆內存中建立對象的特有屬性,並進行默認初始化

5.對屬性進行顯示初始化

6.對對象進行構造代碼塊初始化

7.對對象進行對應的構造函數初始化

8.將內存地址賦值給棧內存中的p變量

 

初始化過程:默認初始化,顯式初始化,構造初始化

繼承:

將類的共有屬性提取出來,將之變為超類,父類

提高了代碼復用性

讓類與類之間產生了關系,因此有了多態的特性

 

只支持單繼承,不支持多繼承

(容易帶來安全隱患:當多個父類中定義了相同功能,但內容不同時,子類不確定執行哪個功能)

但是java保留了這種機制,並用另一種體現形式來完成表示(接口的多實現);

java支持多層繼承,爺爺類-父親類-孫子類,也叫做繼承體系;

在具體調用時,只需創建最子類的對象;

父類可能不能創建對象;

創建子類對象可以使用更多功能,包括共有的和特有的;

查閱父類功能,創建子類對象使用功能;

聚集,聚合,組合

 

若子類和父類有同名變量:

子類訪問本類中的變量,前面加this;

子類要訪問父類的變量,前面加super;

若變量不同名,則this和super(如果父類中有該變量)指向同一個變量

 

若子類和父類中函數同名,則會使用子類的函數;父類的函數被覆蓋(重寫,overide)

沿襲父類功能,但是重寫功能內容.

子類方法覆蓋父類方法條件:

靜態只能覆蓋靜態

必須保證子類權限大於父類,(父類的權限不能為(private))

public >默認權限>private

重載:只看參數列表

重寫:兩個方法需要一模一樣(包括返回值,參數類型)

 

子類和父類的構造函數:絕對不能重寫!

父類先於子類加載,因為在子類的所有構造函數之前都有一句隱世的super()(空參數的父類構造函數);

父類中若有空參數的父類構造函數,子類中的構造函數可以不寫super();

父類中若沒有空參數的構造函數,則子類的每個構造函數第一句需要顯式的寫明super(XXX);

父類中的數據子類可以直接獲取,子類對象在建立時,需要先查看父類是如何對這些數據進行初始化的;

因此子類在對象初始化時,要先訪問父類中的構造函數。

this();或者super();都只能寫在第一行,只能存在一個.

子類中至少有一個構造函數會訪問父類中的構造函數;

extends Object(所有類的上帝,默認父類)

 

final

修飾類,函數,變量

被修飾的類不可以被繼承

被修飾的方法不可以被復寫

被修飾的變量是一個常量,只能賦值一次,可以修飾成員變量和局部變量

所有字母都大寫

修飾類:public final

抽象類和抽象方法

abstract class Student//抽象方法必須存在於抽象類中,不能用該類創建對象,因為沒有意義

{

abstract void study();//抽象方法,內容待定,要被使用,必須有子類復寫該方法

}

子類如果不覆蓋所有的抽象方法,則子類還是一個抽象類

 

父類可以強制子類執行抽象方法;

抽象類和一般類:抽象類多了一些不確定的功能(抽象方法),需要子類具體執行

 

接口:Interface,不能創建對象

特點:

1.所以變量都是public static final

2.所有方法都是public abstract

class interfaceTest implements Interface1

 

 

接口可以被類多實現,一個類中可以實現多個interface:因為多個接口的方法都沒有主體;

一個類在繼承一個父類的同時,可以實現多個接口;

接口之間可以繼承,並且一個接口可以繼承多個接口

 

接口的特點:降低了耦合性

 

多態

函數的多態體現:重載和覆蓋

多態的體現:

父類的引用指向了自己的子類對象

父類的引用也可以接受自己的子類對象

多態的前提:

類與類有關系,要么是繼承,要么是實現;

存在覆蓋;

多態的好處:

提高了程序的擴展性,但是只能使用父類的引用訪問父類中的成員

多態的應用:

 

多態中(非靜態)成員函數的特點:

編譯時期:參閱引用型變量所屬的類中是否有調用的方法,如果有,則編譯可以通過

運行時期:參閱對象所屬類中是否有調用方法

Fu z = new zi();

編譯時,看左邊的Fu類

運行時,看右邊的zi類

面試注意點:

多態中成員變量和(靜態)成員函數的特點:

無論編譯或運行,都參考左邊

靜態綁定,只看引用,只參考左邊;

動態綁定,

 

如果每個子類每次都要調用父類中的共性方法,可以在主函數中或者一個類中創建一個共性方法,

參數以父類對象為准,調用的時候只需要將子類對象傳入即可.

 

object類:所有類的直接或間接父類

內部類:

內部類不用建立對象就可以訪問外部類的成員變量和函數,包括私有

外部類要訪問內部類,必須建立內部類對象

建立在非所屬類中時,需先建立外部類,Outer.Inner in = new Outer().new Inner();

內部類可以私有

內部類訪問外部類成員變量    Outer.this.x

注意:當內部類中定義了靜態成員,則該內部類必須也是靜態的

當外部類中的靜態方法訪問內部類時,內部類也必須是靜態的

 

局部內部類不能靜態

內部類定義在局部時,不可以被成員修飾符修飾

可以直接訪問外部類中的成員

但是不可以訪問所在局部中的變量,只能訪問被final修飾的局部變量

成員修飾符(Static,private…)只能修飾成員變量

 

下面這個例子不會報錯!

Out.method(7);執行完后就會釋放內存!

因此out.method(8);會重新加載

 

匿名內部類:

前提,內部類必須是繼承一個類或者實現接口

abstract class Absdemo

{    abstract void show();}

class Outer

{

...

public void function()

{

new Absdemo()//這是一個Absdemo的一個匿名子類對象

{

void show()

{

System.out.println("匿名內部類!");

}

}.show();

}

...

}

 

格式:new 父類或者接口(){定義子類內容};

其實匿名內部類是一個匿名子類對象,而且這個對象是帶有內容的

匿名內部類中定義的方法最好不要超過3個(方法比較多的話就直接創建一個有名字的子類)

上圖中d.abc();會編譯失敗,因為Absdemo中未定義abc();

AbsDemo d = new AbsDemo(){};//多態

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM