面向?qū)ο蟮母拍?/h1>
舉例:大象裝進冰箱。
面向過程
步驟:打開冰箱--存儲大象--關(guān)上冰箱偶惠。對于面向過程思想春寿,強調(diào)的是過程(動作)。
代表語言:C語言面向?qū)ο?/strong>
步驟:冰箱打開--冰箱存儲--冰箱關(guān)閉(只用找到冰箱即可)忽孽。對于面向?qū)ο笏枷氚蟾模瑥娬{(diào)的是對象(實體)。
特點:
1兄一、面向?qū)ο笫且环N常見的思想厘线,符合人們的思考習慣
2、面向?qū)ο蟮某霈F(xiàn)出革,將復雜的問題簡單化(放在生活中皆的,即是特定的事交給特定的人做)
- 面向?qū)ο笞屧?jīng)在過程中的執(zhí)行者,變成了對象中的指揮者
特征:封裝蹋盆、繼承费薄、多態(tài)(如果未體現(xiàn)這三個特征,就不能說運用了面向?qū)ο蟮乃枷?)
代表語言:C++栖雾,Java楞抡,C#
舉例:人開門
兩個對象:人和門(名詞體現(xiàn)法),開門的方法應該寫在門中(門最清楚打開門這個動作)析藕。
類與對象的關(guān)系
類:用Java語言對現(xiàn)實生活中的事物進行描述召廷,通常只關(guān)注屬性和行為這兩方面。定義類其實就是在定義類中的成員——成員:成員變量<-->屬性账胧,成員函數(shù)<-->行為竞慢。
對象:該類事物的實例,在Java中通過new
關(guān)鍵字來創(chuàng)建的治泥。對象的出現(xiàn)筹煮,是為了封裝數(shù)據(jù)(類的每個實例,都有自己特有的數(shù)據(jù))居夹。
成員變量&局部變量
成員變量和局部變量的區(qū)別:
- 作用范圍:成員變量定義在類中败潦,整個類都可訪問;局部變量定義在函數(shù)准脂、語句劫扒、局部代碼塊中,只在所屬的區(qū)域有效狸膏。
- 存放位置:成員變量存在于堆內(nèi)存的對象中沟饥;局部變量存在于棧內(nèi)存的方法中。
- 生命周期:成員變量隨著對象的創(chuàng)建而存在,隨著對象的消失而消失贤旷;局部變量隨著所屬區(qū)域的執(zhí)行而存在广料,隨著所屬區(qū)域的結(jié)束而釋放。
- 初始化值:成員變量都有默認初始化值遮晚;局部變量沒有默認初始化值 。
匿名對象
Example1:當對象對方法僅調(diào)用一次時拦止,可簡化成匿名對象
Car c = new Car();
c.run();
//可簡寫為
new Car().run();
Example2:匿名對象可以作為實際參數(shù)進行傳遞
Car c1 = new Car();
show(c1);
//可簡寫為
show(new Car());
基本數(shù)據(jù)類型/引用數(shù)據(jù)類型參數(shù)傳遞
封裝
概念:隱藏對象的屬性和實現(xiàn)細節(jié)县遣,僅對外提供公共訪問方式。
好處:將變化隔離汹族;便于使用萧求;提高重用性;提高安全性顶瞒。
原則:將不需要對外提供的內(nèi)容都隱藏起來夸政;把屬性都隱藏,提供公共方法對其訪問榴徐。
private(私有)關(guān)鍵字
- 是一個權(quán)限修飾符
- 用于修飾成員(成員變量和成員函數(shù))
- 被私有化的成員只在本類中有效
將成員變量私有化守问,對外提供對應的get/set方法對其進行訪問。提高對數(shù)據(jù)訪問的安全性坑资。
封裝與私有的區(qū)別
- 私有是封裝耗帕,封裝不是私有。
- 私有僅僅是封裝的一種體現(xiàn)而已袱贮。封裝是面向?qū)ο蟮囊环N特征仿便,隱藏實現(xiàn)的細節(jié),但隱藏細節(jié)不代表只有私有能做到攒巍,只要能做到對方訪問不到就能實現(xiàn)封裝嗽仪。(在Java中,最小的封裝體是函數(shù)柒莉,只要知道函數(shù)的功能(需要的未知內(nèi)容闻坚,返回值是什么 ))。
構(gòu)造函數(shù)
概念:構(gòu)建創(chuàng)造對象時調(diào)用的函數(shù)兢孝。
特點:函數(shù)名與類名相同鲤氢;不用定義返回值類型。
作用:給對象進行初始化西潘。
什么時候定義構(gòu)造函數(shù):在描述事物時卷玉,該事物已存在就具備的一些內(nèi)容,這些內(nèi)容都定義在構(gòu)造函數(shù)中喷市。
一般函數(shù)與構(gòu)造函數(shù)的區(qū)別:
- 構(gòu)造函數(shù):對象創(chuàng)建時相种,就會調(diào)用與之對應的構(gòu)造函數(shù),對對象進行初始化。
一般函數(shù):對象創(chuàng)建后寝并,需要函數(shù)功能就調(diào)用一次箫措。 - 構(gòu)造函數(shù):對象創(chuàng)建時,會調(diào)用且只調(diào)用一次衬潦。
一般函數(shù):對象創(chuàng)建后斤蔓,可以被調(diào)用多次。
public static void main(String[] args)
{
Person p = new Person();
p.Person();//錯誤寫法
p.speak();
p.speak();
}
注意:默認構(gòu)造函數(shù)的特點镀岛;多個構(gòu)造函數(shù)是以重載的形式存在的弦牡。
默認構(gòu)造函數(shù):
創(chuàng)建對象必須要通過構(gòu)造函數(shù)初始化。
- 一個類中如果沒有定義過構(gòu)造函數(shù)漂羊,那么該類中會有一個默認的空參數(shù)構(gòu)造函數(shù)驾锰,
class Demo{}
在編譯成Demo.class文件時會自動創(chuàng)建一個成員Demo(){}
。 - 如果在類中定義了指定的構(gòu)造函數(shù)走越,那么類中的默認構(gòu)造函數(shù)就沒有了椭豫。
重載:一個類中可以有多個不同的構(gòu)造函數(shù),給對象不同的初始化旨指,多個構(gòu)造函數(shù)在類中是以重載的形式來體現(xiàn)的赏酥,重載的特點為方法名相同,方法參數(shù)(參數(shù)個數(shù)谆构、參數(shù)類型)不一樣今缚。
內(nèi)存圖解(構(gòu)造函數(shù)會進棧):
Example1
class Person
{
String name;
int age;
public Person()
{
name = "旺財";
age = 1;
speak(); //可調(diào)用
}
public void speak()
{
Person(); //錯誤寫法,如果要調(diào)用低淡,需寫成new Person();
System.out.println(name + ":" + age);
}
}
Example2:構(gòu)造函數(shù)中可以寫return
姓言,但并不常用
class Person
{
String name;
int age;
public Person(String n, int a)
{
if(a < 0) return;
name = n;
age = a;
}
}
this關(guān)鍵字
概念:代表當前對象喂江。this就是所在函數(shù)所屬對象的引用又固。簡單說:哪個對象調(diào)用了this所在的函數(shù),this就代表哪個對象缀壤。
什么時候使用this關(guān)鍵字:
當在函數(shù)內(nèi)需要用到調(diào)用該函數(shù)的對象時猪杭,就用this餐塘。
當成員變量和局部變量重名,可以用關(guān)鍵字this來區(qū)分皂吮。
用于在構(gòu)造函數(shù)中調(diào)用其他構(gòu)造函數(shù)戒傻。(注意:只能定義在構(gòu)造函數(shù)的第一行,因為初始化動作要先執(zhí)行)
內(nèi)存圖解:
Example1-1:當前構(gòu)造函數(shù)調(diào)用其他構(gòu)造函數(shù)--正確寫法
public class Person
{
private String name;
private int age;
Person(String name)
{
this.name = name;
}
Person(String name,int age)
{
/*調(diào)用Person(String name){...}的構(gòu)造函數(shù)蜂筹,注意不能寫為this.Person(name)需纳,因為構(gòu)造函數(shù)不能通過對象來調(diào)用,也不能寫為Person(name)艺挪,因為這個實際上就是this.Person(name)的省略形式*/
this(name);
this.age = age;
}
}
Example1-2:當前構(gòu)造函數(shù)調(diào)用其他構(gòu)造函數(shù)--錯誤寫法
public class Person
{
private String name;
private int age;
Person(String name)
{
this.name = name;
}
Person(String name,int age)
{
this.age = age;
this(name);
}
}
編譯錯誤:對this的調(diào)用必須是構(gòu)造函數(shù)的第一個語句不翩。
static關(guān)鍵字
定義:static是一個修飾符,用于修飾成員(成員變量和成員函數(shù))
class Person
{
String name; //對象所特有的數(shù)據(jù),成員變量(實例變量)
static String country = "CN"; //靜態(tài)變量(類變量)
}
被static修飾的成員的特點:
- 隨著類的加載而存在
- 優(yōu)先于對象存在
- 被所有對象所共享
- 可以直接被類名調(diào)用(也能被對象調(diào)用)
成員變量和靜態(tài)變量的區(qū)別:
兩個變量的生命周期不同
成員變量隨著對象的創(chuàng)建而存在口蝠,隨著對象的被回收而釋放器钟。
靜態(tài)變量隨著類的加載而存在,隨著類的消失而消失妙蔗。調(diào)用方式不同
成員變量只能被對象調(diào)用傲霸。
靜態(tài)變量可以被對象和類名調(diào)用。數(shù)據(jù)存儲位置不同
成員變量數(shù)據(jù)存儲在堆內(nèi)存的對象中眉反,所以也叫對象的特有數(shù)據(jù)昙啄。
靜態(tài)變量數(shù)據(jù)存儲在方法區(qū)(共享數(shù)據(jù)區(qū))的靜態(tài)區(qū),所以也叫對象的共享數(shù)據(jù)禁漓。
使用的注意事項:
- 靜態(tài)方法在訪問本類的成員時跟衅,只能訪問靜態(tài)成員(非靜態(tài)方法即可訪問靜態(tài)成員孵睬,又可訪問非靜態(tài)成員)
- 靜態(tài)方法中不可以寫this播歼,super關(guān)鍵字
- 主函數(shù)是靜態(tài)的
Example1:在靜態(tài)方法中可通過對象訪問非靜態(tài)方法
class StaticDemo
{
int num = 4;
static int data = 10;
public static void main(String[] args)
{
new StaticDemo().show();
//或 StaticDemo sd = new StaticDemo(); sd.show();
}
public void show()
{
System.out.println(num); //實際上是this.num
System.out.println(data);//實際上是StaticDemo.data
}
}
static的應用——主函數(shù)的特殊之處
public static void main(String[] args)
格式固定;被JVM所識別和調(diào)用掰读。
-
public
:權(quán)限必須最大 -
static
:不需要對象秘狞,直接用主函數(shù)所屬類名調(diào)用即可 -
void
:主函數(shù)沒有具體的返回值( 不然..難道返回給虛擬機?) -
main
:函數(shù)名蹈集,不是關(guān)鍵字烁试,只是一個jvm識別的固定的名字 -
String[] args
:主函數(shù)的參數(shù)列表,字符串類型數(shù)組
默認情況下傳入的值為一個空數(shù)組拢肆,若要傳值减响,可以通過:
javac 類名
java 類名 XX XX ...(字符串參數(shù))
注意:
class MainDemo
{
public static void main(String[] args)
{
...
}
public static void main(int x) //函數(shù)的重載而已,這樣寫不會報錯
{
...
}
}
內(nèi)存圖解
- 執(zhí)行java StaticDemo2后郭怪,會開辟空間(棧支示、堆、方法區(qū)(分為非靜態(tài)區(qū)和靜態(tài)區(qū)(存儲靜態(tài)成員)))鄙才,棧是運行區(qū)颂鸿,方法區(qū)是代碼置放區(qū)。
- 非靜態(tài)區(qū)和靜態(tài)區(qū)中的方法是所有該類的對象都具有的功能攒庵,這些對象唯一的區(qū)別是封裝的數(shù)據(jù)不一樣嘴纺。
- 當執(zhí)行main方法的第一行時,加載Person類浓冒,在classpath路徑下找是否有Person.class文件栽渴,若沒有設(shè)置classpath,則在當前目錄下找稳懒,找到后會把Person.class文件加載進內(nèi)存熔萧。
靜態(tài)什么時候使用?
靜態(tài)變量
當對象所具備的成員變量的值都是相同的,那么這個成員就需要被靜態(tài)修飾佛致;如果是不同的贮缕,那就是對象的特有數(shù)據(jù),必須存儲在對象中俺榆,是非靜態(tài)的感昼。-
靜態(tài)函數(shù)
函數(shù)是否用靜態(tài)修飾,只參考一點——該函數(shù)功能是否需要訪問到對象的特有數(shù)據(jù)(即非靜態(tài)的成員變量)罐脊,如果需要定嗓,該功能就是非靜態(tài)的;如果不需要萍桌,該功能就是靜態(tài)的宵溅,當然也可以將其定義為非靜態(tài),但是非靜態(tài)需要被對象調(diào)用上炎,而僅創(chuàng)建對象調(diào)用非靜態(tài)的沒有訪問特有數(shù)據(jù)的方法恃逻,該對象的創(chuàng)建沒有意義,會造成堆空間的浪費藕施。class Demo { int age; static int num = 9; Demo(int age) { this.age = age; } public static void speak() { System.out.println("hahaha"); } } class StaticDemo { public static void main(String[] args) { //Demo d = new Demo(30); //d.speak(); Demo.speak(); } }
靜態(tài)代碼塊
特點:隨著類的加載而執(zhí)行寇损,而且只執(zhí)行一次。
作用:用于給類進行初始化裳食。(構(gòu)造函數(shù)是給對象初始化的矛市,注意有的類可能不需要對象(如,所有的函數(shù)都是靜態(tài)的))
class StaticCode
{
static int num; //在此處也可以賦值诲祸,即static int num = 10浊吏,但在此處只能進行一次賦值動作,而在靜態(tài)代碼塊里還能對其進行更多的處理
static
{
num = 10;
num *= 3;
System.out.println("hahaha");
}
static void show()
{
System.out.println(num);
}
}
class StaticCodeDemo
{
public static void main(String[] args)
{
//new StaticCode().show();
//new StaticCode().show();
StaticCode.show();
}
}
一般會用靜態(tài)代碼塊對類進行初始化的救氯,那么在這個類中找田,全是靜態(tài)成員。
構(gòu)造代碼塊
類中的獨立代碼塊径密。
構(gòu)造代碼塊:可以給所有對象進行初始化午阵,具有通用性
構(gòu)造函數(shù):給對應的對象(調(diào)用該構(gòu)造函數(shù)的對象)進行針對性的初始化。
構(gòu)造代碼塊比構(gòu)造函數(shù)先執(zhí)行享扔。
class Person
{
private String name;
{
cry();
}
Person()
{
name = "baby";
// cry();
}
Person(String name)
{
this.name = name;
// cry();
}
public void cry()
{
System.out.println("哇哇");
}
public void speak()
{
System.out.println("name:"+name);
}
static void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
public static void main(String[] arg)
{
Person p1 = new Person();
p1.speak();
Person p2 = new Person();
p2.speak();
new Person();
//以上會輸出三遍“哇哇”
Person.show(); //不會輸出“哇哇”底桂,即不會執(zhí)行構(gòu)造代碼塊中的內(nèi)容
}
}
不允許其他類創(chuàng)建某類的對象
class ArrayTool
{
private ArrayTool(){}//該類中的方法都是靜態(tài)的,所以該類是不需要創(chuàng)建對象的惧眠;為了保證不讓其它類創(chuàng)建該類對象籽懦,可以將構(gòu)造函數(shù)私有化
public static int getMax(int[] arr)
{
...
}
public static void selectSort(int[] arr)
{
...
}
}