面向對象
面向對象是一種思考問題的方式,以對象的形式來思考問題
類:是對象描述 ,類是對象的抽象(抽象:提取對象的共性)
對象:是實實在在存在的個體,它是類具體實現,也叫做類的實例
對象創建的過程(new 類名()),叫做對象的實例化
類的定義:
[修飾符] class 類名
{
構造器 //對應的是對象的創建方式
成員變量 //對應的是對象的屬性
成員方法 //對應的是對象的行為(功能)
}
構造器(構造方法,構造函數):
如果不提供有參數的構造器,jvm會提供一個默認的無參構造器
[修飾符] 類名()
{
方法體
}
如果類中提供了有參構造器,則jvm就不再提供無參構造器,如果需要使用無參構造,則需要自己定義
有參構造器
[修飾符] 類名(參數數據類型 參數名...)
{ }
如果一個類中同時存在,無參構造器和多個有參構造器,這個叫做構造器的重載
成員變量:
存在于類中,但是處于成員方法以外
作用域: 從聲明的地方開始,到類的結束
成員變量是有默認值(缺省值)的,根據數據類型的不同,初始值是不同,如果是int類型的, 初始值是0 ,如果是引用類型,初始是null
成員變量,可以用修飾符修飾
局部變量:
存在于成員方法中,注意:參數是特殊的局部變量
作用域:從聲明的地方開始,到方法的結束
局部變量沒有默認值
只能用final修飾
成員方法:
[修飾符] void|返回值的數據類型 方法名([參數類型 參數名 , ...])
{
方法體 也叫作代碼塊
}
對象的創建和使用
對象的創建
類名 對象名 = new 類名([參數,...]);
對象的使用
獲得對象的屬性
數據類型 變量名 = 對象名.屬性名
修改對象的屬性
對象名.屬性名 = 屬性值 ;
調用對象的方法
對象名.方法名();
方法的重載
1,在同一個類中
2,方法名相同
3,參數不同:參數個數,參數順序,參數類型 (滿足其中之一,則視為參數不同)
this關鍵字的使用
每一個類中都有兩個特殊的成員變量,一個是this,一個是super
this 里面存儲的當當前對象的地址 ,代表就是當前對象
this有兩個用法:
1,當成員變量名和局部變量名發生沖突的時候,可以使用 this.變量名 標注成員變量
2,當一個構造器需要調用本類的其他構造器時,可以使用this()進行調用,但是this()必須寫在構造器方法體的第一行
static(靜態的)是修飾符,可以用來修飾成員變量和成員方法
static 修飾成員變量
有static修飾的成員變量叫做類變量 也叫做 類成員變量 也叫做靜態變量
沒有static修飾的成員變量 叫做實例變量 這里的實例指的是對象
有static修改的成員變量,是所有對象共有的變量
使用及修改需要 用類名.變量名
static 修飾成員方法
有static修飾的成員方法叫做類方法,也叫做靜態方法
沒有static修飾的成員方法叫做實例方法 這里的實例指的是對象
有static修飾的成員方法是所有該類對象共有的方法
調用的時候,可以使用對象名.方法名(); 也可以使用類名.方法名();
java程序的運行,首先jvm將class文件加載到jvm中,這時會同時把靜態變量和靜態方法同時加載到jvm
當創建該類對象的時候,jvm才會加載實例變量和實例方法
靜態方法可以訪問靜態變量和靜態方法,但是不能訪問實例變量和實例方法
實例方法可以訪問靜態方法和靜態變量也可以訪問實例方法和實例變量 即 實例方法可以訪問類中所有的變量及方法
static 修飾代碼塊
代碼塊:一般用作初始化工作
{ 代碼 }
有static修飾的代碼塊,叫靜態代碼塊,一般用于初始化一些靜態的變量
靜態代碼塊,在class文件被加載時執行,程序運行期間,只會執行一次
當第一次創建對象的時候,執行順序是
先加載class文件,然后是按照順序 加載靜態變量,靜態方法,靜態代碼塊(這里的順序指的是源文件的編碼的順序)
然后會執行一次靜態代碼塊
然后按照順序 執行實例代碼塊
創建對象的時候是先執行實例代碼塊再執行構造器
沒有static修飾的代碼塊,叫做實例代碼塊,一般用于初始化工作
實例代碼塊,每次創建對象時,都會執行一次
引用:
Person p = new Person() ;
這個p就是一個引用數據,其實p里存的不是真正的對象,而是對象在內存中的地址
Java中的內存 棧 堆 方法區
棧中的數據:如果是基本數據類型,則存儲的是數據
如果是引用數據類型,則存儲的是地址
所有的方法的運行都是在棧中,每運行一個方法,jvm就會在棧內存開辟一個空間,用來存儲方法中的變量
引用數據類型,在棧中存儲的是一個地址,這個地址指向的是對象在堆內存中的實際位置
每創建一個新的對象,jvm就會在堆內存中去開辟一個空間,存放該對象的屬性,而方法存在于方法區
Java中的引用數據類型有哪些?
數組,類,接口
思考:數組中數,存在哪? //在堆內存中
int a = {1,2,3,4,5,6} ;
棧內存中的a的值是什么? 是地址 指的是數組中的數在堆內存中的實際的位置
引用
Person p = new Person() ;
p 中存儲的是對象在內存中的地址
程序運行過程中,一旦新建對象,那么該對象時存儲在堆內存中
方法的運行都是在棧內存中,每運行一個方法,jvm就會在棧內存中開辟一個空間,用于存儲該方法運行時產生的變量
如果變量的數據類型是基本數據類型 則存儲的是真實數據
如果變量的數據類型是引用數據類型 則存儲的是數據在堆內存中的地址
this 關鍵字
Java的類中有兩個特殊的成員變量,一個是this,代表當前對象的引用,this中存放的是當前對象的地址
另一個是super 代表的是當前對象的父類對象 super中存放的是當前對象的父類對象在堆內存中的地址
this關鍵字的作用:
1,當類中的成員變量和局部變量重名時,可以通過this.變量名來標注成員變量
2,當一個構造器需要調用類中其他的構造器時,可以使用this([參數...])來進行調用
注意:構造器只能被構造器所調用,不能再成員方法中調用構造器
如果一個構造器需要調用另一個構造器,則this([參數....])必須位于構造器方法體中的第一行
static關鍵字 就是一個修飾符 可以用來修飾成員變量,成員方法,代碼塊,類
static修飾成員變量
有static修飾的成員變量叫類變量 也叫做 靜態變量 是該類所有對象共享的變量 調用方法推薦使用類名.變量名
沒有static修飾的成員變量叫做實例變量 這里的實例指的是對象
static修飾成員方法
有static修飾的成員方法叫做類方法,也叫做靜態方法,是該類所有對象共享的方法 ,調用 推薦使用 類名.方法名([參數...]);
沒有static修飾的成員方法叫做實例方法,調用 對象名.方法名([參數....]);
static修飾代碼塊
有static修飾的代碼塊叫做靜態代碼塊,主要就是用來做一些初始化工作,比如初始化靜態變量
在程序運行的整個過程中,只會執行一次
沒有static修飾的代碼塊叫做實例代碼塊,主要用于一些初始化的工作,比如初始化實例變量
每創建一個對象,就會執行一次
實例代碼塊和構造器誰先執行? 代碼塊先執行
注意:
1,靜態代碼塊,靜態方法只能訪問靜態變量,靜態方法,不能訪問實例方法,實例變量
2,實例方法,實例代碼塊 可以訪問該類中所有的方法及變量
jvm類加載流程
程序運行時,是先加載class文件,同時加載的還有該class文件中的靜態變量,靜態方法,靜態代碼塊
當創建對象時,jvm才會分配空間,加載實例變量,實例方法,實例代碼塊
在整個程序運行的過程中,一個class文件只會被加載一次
包:是Java語言當中用來管理類,接口等源文件的一個管理工具。
包的使用和聲明:
包的聲明:
package 包名;
1,包名一般采用多級包名;package com ; 一級包名 package com.zdsoft; 二級包名
2,包名一般使用小寫字母
3,包名不能以java和javax開頭
4,一般情況主包名采用的是倒置的域名+項目名稱+功能名稱 比如:com.huawei.netopen.util com.zdsoft.qq.login
5,包的聲明語句必須位于源文件的第一行
包的導入:
什么時候需要導入包?
當一個包里面的類需要引用另外一個包里面的類時,就需要導入 關鍵字 import
語法:
import 包名.類名|接口名; //這是導入指定包中的指定的類 或者指定的接口名
import 包名.* ; //這是導入指定包中的所有的類和接口
注意:導包語句寫在源文件 聲明包名之后,聲明類之前;
訪問權限修飾符
private 修飾的成員方法和成員變量不能被其他類訪問,本類中可以訪問
也就是說,如果你在其他的類中創建了該類對象,那么,這個對象是不能調用以private修飾的所有的成員方法和變量
(default) 如果成員變量和成員方法前面沒有訪問權限修飾符 則 默認為default
被default修飾的成員變量和成員方法,只能被本類和與其在同一個包中的其他類訪問
protected 被該修飾符修飾的成員變量和成員方法可以被本類和與其在同一個包中的其他類以及不與其在同一個包中的子類訪問
public 被該修飾符修飾的成員變量和成員方法可以被所有的類訪問
final修飾符 (final的中文意思 :最終的)
被final修飾的變量最多只能被賦值一次
被final修飾的變量一經賦值,則不能再被改變
final int a = 10 ;
a = 20 ; //這是錯誤的
被final修飾的成員變量,成員必須賦初始值,一經賦值則不能被改變
被final修飾的局部變量,可以先聲明,等到使用的時候再賦值,但是只能被賦值一次
面向對象的三大特點
封裝,繼承,多態
封裝:
這里講的封裝,主要是對屬性和方法的封裝,
對屬性的封裝:
需要把屬性私有化,然后對外提供公共的訪問方法
對方法的封裝:
將外部可以訪問的方法使用public修飾,將外部不能訪問的方法使用private修飾
繼承:
將多個具有相同屬性和行為的類的相同的屬性和行為抽取出來,封裝到一個單獨的類中,
這時,具有相同屬性和行為的類就不必要重復的編寫這些行為和屬性,只需要繼承封裝后的那一個新類就能擁有這些屬性和行為
這些具有相同屬性和行為的類叫做子類,封裝的新類叫做父類或者超類
如:狗 , 貓 , 豬 都有共同的屬性 性別,年齡 ,都有共同行為 吃 ,睡
就將這些相同的屬性和行為抽取出來,封裝一個新類 動物
動物 有性別 ,年齡 等屬性 有 吃,睡等行為
此時:狗只需要繼承動物 就可以擁有動物的屬性和行為
語法
[修飾符] class 狗 extends 動物
{ }
注意:子類不能繼承父類私有的屬性和方法
子類除了能夠擁有父類非私有的屬性和方法外,還有可以擴展自己特有的屬性和方法
包的創建和使用
包:是Java語言中用來管理類,接口等源文件的一個管理工具,類似于windows系統中的文件夾
包的聲明:
package 包名 ;
聲明包時需要注意的點:
1,采用多級包名
2,一般使用小寫字母
3,包名不能以java或javax開頭
4,一般情況主包名采用的是倒置的域名.工程名.功能名
5,包的聲明語句必須位于源文件的第一行
包的導入:
需要使用關鍵字 import
import 包名.類名|接口名 ; //導入指定包中指定的類或者接口
import 包名.* ; //導入指定包中所有的類和接口
什么時候需要導入包?
當一個包里面的類,需要引用另一個包里面的類時,則需要導入包
訪問修飾符 (public private (default) protected)
private 私有的,由private修飾的變量和方法只能在本類中被訪問
default 默認的(當變量及方法沒有訪問權限修飾符時則默認為default), 由default修飾的變量和方法可以在本類訪問以及與其在同一個包中的其他類訪問
protected 受保護的 在default的基礎上,增加了其他包中的繼承了該類的子類
public 公共的 可以被其他所有的類方問
final修飾符(中文含義:最終的)
被final修飾的變量最多只能被賦值一次,一經賦值就不能改變
封裝
對方法和屬性的封裝
對屬性的封裝:
將屬性私有化,然后對外提供公共訪問接口 提供 get set方法
對方法的封裝:
將你不愿意提供給外界訪問的方法私有化(用private修飾),希望外界訪問的方法共有化(用public修飾)
繼承
父類是子類的抽象
把具有相同屬性和行為的多個類的相同的屬性和行為抽取出來,封裝成一個新的類,
這個新的類叫做父類,這具有相同屬性和行為的多個類叫做子類,需要繼承父類。
繼承的語法
[修飾符] class 子類名 extends 父類名
{
}
子類可以有自己擴展的屬性和方法
繼承的特點:
1,Java語言當中,如果一個類沒有明確的指出它父類,那么默認繼承的Object類
2,Java語言當中,類的繼承只支持單繼承,即一個類只能有一個直接父類 extends 后只跟一個父類名
3,Java語言當中,支持多層繼承
4,Java語言當中,子類只能繼承父類非私有的屬性和方法,不能繼承父類的構造器
注意:
1,不要為了獲得某個類中的功能,而去繼承這個類
2,繼承關系中,類與類之間一定要有所屬關系,如:狗是動物的一種,動物是生物的一種
包對于繼承的影響(關系到訪問權限修飾符)
private 修飾的屬性和方法是私有的,只能在本類訪問,不能繼承
default 修飾的屬性和方法,可以被本類訪問,可以被同包內中的其他類所訪問 能同包內中的子類所繼承
protected 修飾的屬性和方法,在default的基礎上,增加了可以被其他包中的子類繼承
public 修飾的屬性和方法,可以被任意類訪問
子類對象的創建流程
當新創建一個子類對象時,實際上是先調用了父類的無參構造器,然后才調用了子類自身的構造器
每一個子類構造器中默認的第一行有隱式調用父類的無參構造器
如果父類只提供了有參的構造器,那么子類需要在每一個構造器的第一行顯示的調用父類的有參構造器
super關鍵字
每一個類中都有兩個特殊的成員變量,一個是this 代表當前對象,一個是super,代表的父類對象
this有兩個作用:
當成員變量和局部變量發生沖突的時候,可以使用this.變量名來標注成員變量
當一個構造器中需要調用本類的另一個構造器時,可以使用this([參數]);來進行調用,但是this()必須寫在構造器的方法體的第一行
super的作用:
1,當子類中的變量和父類中的成員變量重名時,可以使用super.變量名來標注 父類的成員變量
2,當子類的構造器調用父類的構造器時,使用super([參數]); 注意:super()必須寫在子類構造器方法體中的第一行
所以不能同時顯式的存在super(),this()。
3,當在子類的方法,需要調用父類的方法時,super.父類方法名([參數]);
方法的重寫 override
當子類從父類繼承過來的方法,無法滿足子類的功能需求時,子類需要對該方法進行重新實現,這個個過程叫做方法的重寫,也叫做方法的覆蓋,或者復寫
方法重寫的條件:
1,一個類需要重寫另一個類中的方法,那么它們一定要有繼承關系
2,子類中重寫的方法的訪問權限修飾符的權限一定要大于等于父類方法的訪問權限
3,子類重寫的方法的方法名,參數列表,返回值的數據類型必須和父類保持一致
多態:就是指的是一個事物多種形態
方法的多態
方法的重載(發生在本類中)
方法的重寫(發生在繼承中)
變量的多態(這里主要指對象的多態)
1,向上轉型
父類變量 Father f ; 既可以保存父類對象的引用,也可以保存子類對象引用
Father (父類) Son(子類)
Father f ;
Son s = new Son();
f = s ;
注意:當對象發生向上轉型時,只會保留父類中可以被繼承的方法和變量,子類重寫的方法會保留
2,向下轉型
子類變量可以存儲子類對象的引用,也可以存儲父類對象的引用
注意:如果需要進行向下轉型,則應該先進行向上轉型
抽象方法:
當父類中的方法不確定子類應該實現什么樣的功能時,可以把這個方法聲明為抽象方法
抽象方法的聲明語法:
[修飾符(public)] abstract void|返回值數據類型 方法名([參數類型 參數名]);
注意:抽象方法必須存在于抽象類中,抽象方法沒有方法體
抽象類的聲明語法:
[修飾符(public)] abstract class 類名
{
成員變量
成員方法(可以是抽象的,也可以不是抽象的)
代碼塊
}
抽象類使用注意點:
1,抽象類不能被實例化(不能創建對象, 不能 new)
2,抽象類就是用來被繼承的
3,抽象類中可以沒有抽象方法,但是抽象方法一定要存在于抽象類中
4,抽象類中可以存在具象方法(有方法體的方法)
5,抽象類的子類必須實現(重寫)抽象類中的所有的抽象方法,否則子類就需要聲明為抽象類
6,抽象方法被重寫的時候,需要去掉關鍵字abstract,并為方法加上方法體