<a target="_blank" href="http://www.javahelp.com.cn/">java幫幫-it資源分享網</a>
三、黑馬程式員—面向對象(1)
第三篇:
1、什麼叫面向對象?
面向對象(object-oriented,簡稱 oo)就是一種常見的程式結構設計方法。
面向對象思想的基礎是将相關的資料和方法放在一起,組合成一種新的複合資料類型,然後
使用新建立的複合資料類型作為項目的基礎。
面向對象是一個很抽象的概念,它相對面向過程而言。
過程與對象都是一種解決問題的思想。
面向過程:強調的是功能行為,一種過程,先幹啥,再幹啥;
面向對象:将功能封裝到對象裡,強調的是具備某功能的對象;
按照面向對象的思想,可以把任何的東西看做對象!
面向對象的三個特征:
封裝(encapsulation);
繼承(inheritance);
多态(polymorphism)。
我的總結:
面向過程:強調的是具體的功能實作;(執行者)
面向對象:強調的是具備功能的對象。(管理者)
2、類
類(class)是 java 語言的最小程式設計機關,也是設計和實作 java 程式的基礎,本部分将深入介
紹類的相關知識。
類的概念
類是一組事物共有特征和功能的描述。類是對于一組事物的總體描述,是按照面向對象技術
進行設計時最小的機關,也是組成項目的最基本的子產品。類的概念是抽象的,類似于建築設
計中的圖紙,是對于現實需要代表的具體内容的抽象。類隻包含架構結構,而不包含具體的
資料。是以類代表的是總體,而不代表某個特定的個體。
我的總結:類是抽象的,對象是具體的,實實在在的!
類的定義:
[修飾符] class 類名{
1~n 個構造方法;
0~n 個字段;
0~n 個方法
}
定義類,其實就是定義類裡面的對象
對象包含:
狀态;(屬性)
功能、行為;(方法)
通過類來描述對象;
狀态--------成員變量;
功能、行為——方法;
eg:
class person{
//屬性
private string name;
private int age;
private int sal;
//方法
public void show(){
system.out.println("個人情況:"+name+age+sal);
}
3、構造方法
構造方法:用來構造類的執行個體(每一個類都預設有一個無參的構造方法,得使用 new 調用)
字段:類或對象所包含的資料,對類狀态的一種描述;
方法:類或對象的特征或行為
作用:
給類中的字段進行初始化,可以用來建立對象。
特點:
方法名與類名相同
不用定義傳回值類型
不需要寫 return 語句
注意:
預設構造方法的特點。
多個構造方法是以重載的形式存在的。
構造方法的重載:(需要哪個就去适配哪個,調用哪個)
this([實參]);調用目前類的構造方法
注意: this([實參]);必須放在構造器的第一行;
對象的産生格式:
類名稱 對象名 = new 類名稱();
因為有(),是以是方法,實際上它就是構造方法,并且是非私有的構造方法。
如:cellphone cp = new cellphone();
public person(string name) {
super();
this.name = name;
public person(string name, int age) {
this.age = age;
public person(string name, int age, int sal) {
this.sal = sal;
4、static 關鍵字
随着類的加載而加載
優先于對象存在
被所有對象所共享
可以直接被類名調用
使用注意:
靜态方法隻能通路靜态成員
但是非靜态成員可以通路靜态成員;
靜态方法中不可以使用 this,super 關鍵字
主方法(main)是靜态的(可以利用類名去調用靜态的 main 方法,很正常!但是會陷
入死循環,導緻記憶體溢出,jvm 自動停止!)
public static void main(string[] agrs){}
可修飾字段,方法。
用 static 修飾的成員表示它屬于這個類共有,而不是屬于該類的單個執行個體。
static 修飾的字段 == 類字段
static 修飾的方法 == 類方法
沒使用 static 修飾的字段和方法,成員屬于類的單個執行個體,
不屬于類。
沒有 static 修飾的字段 == 執行個體字段
沒有 static 修飾的方法 == 執行個體方法
類和執行個體通路字段和方法的文法:
通路類成員: 類.字段 類.方法
通路執行個體成員: 執行個體.字段 執行個體.方法
static 修飾的字段和方法,既可以通過類調用,也可以使用執行個體調用;
沒 static 修飾的字段和方法,隻能使用執行個體來調用(建議使用:類名來調用; 其實在底層,
對象調用類成員,也會轉換類名調用)
static 關鍵字不能與 this,super 同時連用!
5、匿名對象
一個沒有名字的對象, 建立了一個對象出來,沒有賦給一個變量;
對方法或字段隻進行一次調用時;
可作為實際參數進行傳遞;
隻在堆裡面開辟存儲區域,
隻能使用一次, 使用完就被銷毀了;
何時使用?隻拿來用一次!!
new person();表示匿名對象,沒有名字的對象
new person().age = 17;//使用一次之後就被銷毀了
6、this 關鍵字
特點:this 表示目前對象。
目前對象 ←→ 目前正在調用執行個體成員的對象
換言之:誰調用了方法,誰就是目前對象。
什麼時候使用 this 關鍵字呢?
方法間的互相調用;
this.字段;
構造器中互相調用,但是此時 this([參數])必須寫在構造方法第一行。
this 不能用在 static 修飾的方法裡和 static 修飾的代碼塊裡;
eg:構造方法中的 this.name = name;
7、面向對象之封裝
封裝的兩個含義:
1.把對象的狀态和行為看成一個統一的整體,将二者存放在一個獨立的子產品中(類);
2."資訊隐藏", 把不需要讓外界知道的資訊隐藏起來,盡可能隐藏對象功能實作細節,字段;
封裝機制在程式中的展現是:把描述對象的狀态用字段表示,描述對象的行為用方法表示,
把字段和方法定義在一個類中,并保證外界不能任意更改其内部的字段值,也不允許任意
調動其内部的功能方法。
程式中的一種展現:通常将類中的成員變量私有化 (private) ,通過對外提供方法
(setxxx,getxxx),可對該變量(xxx)進行通路。
boolean 類型的變量沒有 getxx,隻有 isxx;
class person1{
public string getname() {
return name;
public void setname(string name) {
public int getage() {
return age;
public void setage(int age) {
8、通路修飾符
private 類通路權限:本類内部可以通路,不能繼承到子類;
default 什麼都不寫,包通路權限:本類内部可以通路,同包其他類也可以通路,同包可繼承;
protected 子類通路權限:本類内部可以通路,不同包的子類也可以通路,同包其他類也可以
通路,能繼承到子類;
public 公共通路權限:任何地方都可以通路,能繼承到子類;
9、類的設計分析
分析思路:
根據要求寫出類所包含的字段;
所有的字段都必須私有化;
封裝之後的字段可通過 setter 和 getter 設值和取得;
按需求可添加若幹構造方法;
根據需求可添加相應的方法;
類中的所有方法都不要直接處理(輸出列印),而是交給調用者去處理。
10、面向對象之繼承
首先有反映一般事物特性的類,然後在此基礎上反映出特殊事物的類;
也就是說:繼承是一種從一般到特殊的關系;
1、提高了代碼的複用性。
2、讓類與類之間産生關系,有了這個繼承關系才有了多态的特性。
3、java 語言中隻支援單繼承(有别于 c 語言)。
因為多繼承容易帶來安全隐患(父類多了, 功能相同的話,就會出現調用不确定性嗎,
覆寫一個方法,到底覆寫的誰的?)。
ps:接口可以實作多繼承
4、java 支援多層繼承,object 是每個類的超類,實作樹形結構。
繼承是多态的前提。
對類而言,隻支援單繼承。接口可以實作多繼承
格式:
[修飾符] class subclass extends superclass
按照這種關系,我們把 superclass 類稱為父類或基類,把 subclass 稱為子類或派生類或拓
展類;
java.lang.object 是所有類的父類,
object 要麼是直接父類要麼是間接父類。
學生屬于人的一種特殊情況,此時我把人的共性寫在 person 類裡面,為了讓學生擁有這
些共性(别的比如老師也可以有這些共性),然後我就讓學生來拓展 person 類。
子類與父類的關系:
子類拓展父類(子類是父類的一種特殊情況)
主要是以父類為基礎,然後添加屬于自己的字段和方法。
父類的私有成員子類不能繼承到;父類的構造方法不能被繼承;
java 隻支援單繼承,不支援多繼承;//不然的話,比如 show 方法,繼承了多個,不知道到底
調用那一個。
一個類有且隻有一個直接父類;
一個類沒顯示的繼承其他的一個類的時候,預設的直接父類就是 object 類;
student 的直接父類是 person,object 類也是 student 類的父類,但是是間接父類;
一旦一個類顯示的繼承了其他的一個類的時候,此時預設的直接父類 object 就會被取消;
java 裡一個類隻能有一個直接父類;java.lang.object 是所有類的父類,object 要麼是直接父類
要麼是間接父類。
子類對象執行個體化過程
在繼承操作中,對于子類對象的執行個體化:
子類對象在執行個體化之前必須首先調用父類中的構造方法之後再調用自身的構造方法。
11、子類通路父類和方法覆寫
子類不能直接通路父類的私有成員;
但是子類可以調用父類中的非私有方法來間接通路父類的私有成員。
person 類中有私有字段 name,student 繼承 person
new sudent().name; ×
new student().getname(); √
方法覆寫産生原因:
當父類中某個方法不适合于子類時,子類出現父類一模一樣的方法.
判斷必殺技:子類方法前加上@override 能編譯通過,表明是方法的覆寫。
調用被覆寫的父類方法:使用 super.方法名(實參);
方法覆寫時應遵循的原則(一同兩小一大):
(一同):方法簽名必須相同;
(兩小):
子類方法的傳回值類型比父類方法的傳回值類型更小或相等
子類方法聲明抛出的異常應比父類方法申明抛出的異常更小或相等;
(一大):子類方法的通路權限應比父類方法更大或相等;
子類需要覆寫父類方法。
當父類的某個方法不适合于子類本身的特征行為時就當覆寫父類中應當改變的方法。
12、super 關鍵字和調用父類構造方法
表示父類對象的預設引用
如果子類要調用父類被覆寫的執行個體方法,可用 super 作為調用者調用父類被覆寫的執行個體方法。
使用 super 調用父類方法
使用 super 調用父類的構造方法
調用構造方法
本類中調用另一個重載構造方法用 this(參數清單)
子類構造方法調用父類構造方法用 super(參數清單)
子類調用父類的構造方法時:
super 必須放在第一句
java 在執行子類的構造方法前會先調用父類無參的構造方法,其目的是為了對繼承自父類的
成員做初始化操作。
子類在建立對象的時候,預設調用父類的無參構造方法,要是子類構造方法中顯示指定調用
父類其他構造方法,就調用指定的父類構造方法,取消調用父類無參構造方法。
package reviewdemo;
class a{
string name;
a(){
system.out.println("父類預設隐式的構造方法!");
a(string name){
system.out.println("父類顯式的構造方法!");
class b extends a{
b(){
super(null);
system.out.println("子類預設隐式的構造方法!");
public class demo10 {
public static void main(string[] args) {
new b();
結果:父類顯式的構造方法!
子類預設隐式的構造方法!
13、面向對象之多态
多态:指同一個實體同時具有多種形式
好比,你去面館吃面,說我要吃面,那麼;老闆給我牛肉面,雞蛋面等都可以,
這就是說"面"有多種形态,也就是說實體有多種形态;
編譯時的類型由聲明該變量時使用的類型決定,運作時的類型由實際賦給變量的對象決定。
如果編譯時類型和運作時類型不同,就出現多态。
前提:student extends person:
person p = new person();
student s = new student();
person p = new student();//多态
引用關系:父類變量指向子類執行個體對象
實作多态的機制:
父類的引用變量可以指向子類的執行個體對象,而程式調用的方法在運作期才動态綁定,就是引
用變量所指向的真正執行個體對象的方法,也就是記憶體裡正在運作的那個對象的方法,而不是引
用變量的類型中定義的方法。
多态的作用:
把不同的子類對象都當作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,
做出通用的程式設計,以适應需求的不斷變化。
隻修改方法的實作,不必修改方法的聲明
繼承是多态産生的前提條件;
分類:
編譯時多态:方法重載
運作時多态:方法覆寫
package test;
class dog{
void eat(){
system.out.println("一般的狗吃一般的狗糧!");
class hashdog extends dog{
system.out.println("哈士奇吃哈士奇的狗糧!");
class zangaodog extends dog{
system.out.println("藏獒吃藏獒的狗糧!");
//定義一個動物園喂的方法
class zoo{
void feed(dog d){
d.eat();
public class demo11 {
dog hd = new hashdog();
dog zd = new zangaodog();
zoo z = new zoo();
z.feed(hd);
z.feed(zd);
輸出:
哈士奇吃哈士奇的狗糧!
藏獒吃藏獒的狗糧!
14、引用變量類型轉換
向上轉型(子類→父類):(自動完成)
父類名稱 父類對象 = 子類執行個體 ;
向下轉型(父類→子類):(強制完成)
子類名稱 子類對象 = (子類名稱)父類執行個體 ;
對象名 instanceof 類
判斷指定的變量名此時引用的真正類型是不是目前給出的類或子類;
我的總結:對象的類型和類必須有繼承關系
class a extends b{}
b b = new a();
if(b instanceof a){ ...