零基础学java(6)——面向对象的基本特征
第六章 面向對象的基本特征
目錄
- 第六章 面向對象的基本特征
- 6.1 封裝
- 6.2 構造器
- 6.3 關鍵字this
- 6.4 包
- 6.5 eclipse的使用
- 6.6 面向對象的基本特征之二:繼承
- 6.7 關鍵字super
- 6.8 方法的重寫
- 6.9 非靜態代碼塊
- 6.10 實例初始化過程
- 6.11 面向對象的基本特征之三:多態
面向對象的基本特征:
1、封裝
2、繼承
3、多態
6.1 封裝
1、好處:
(1)隱藏實現細節,方便使用者使用
(2)安全,可以控制可見范圍
2、如何實現封裝?
通過權限修飾符
面試題:請按照可見范圍從小到大(從大到小)列出權限修飾符?
| private | √ | × | × | × |
| 缺省 | √ | √ | × | × |
| protected | √ | √ | √ | × |
| public | √ | √ | √ | √ |
權限修飾符可以修飾什么?
類(類、接口等)、屬性、方法、構造器、內部類
類(外部類):public和缺省
屬性:4種
方法:4種
構造器:4種
內部類:4種
3、通常屬性的封裝是什么樣的?
當然屬性的權限修飾符可以是private、缺省、protected、public。但是我們大多數時候,見到的都是private,然后給它們配上get/set方法。
示例代碼:標準Javabean的寫法
public class Student{//屬性私有化private String name;private int age;private boolean marry;//公共的get/setpublic void setName(String n){name = n;//這里因為還沒有學習this等,可能還會優化}public String getName(){return name;}public void setAge(int a){age = a;}public int getAge(){return age;}public void setMarry(boolean m){marry = m;}public boolean isMarry(){//boolean類型的屬性的get方法,習慣使用把get換成isreturn marry;} }6.2 構造器
1、構造器的作用:
(1)和new一起使用創建對象
(2)可以在創建對象的同時為屬性賦值
public class Circle{private double radius;public Circle(){}public Circle(double r){radius = r;//為radius賦值} }2、聲明構造器的語法格式:
【修飾符】 class 類名{【修飾符】 類名(){//無參構造}【修飾符】 類名(形參列表){//有參構造} }3、構造器的特點:
(1)所有的類都有構造器
(2)如果一個類沒有顯式/明確的聲明一個構造器,那么編譯器將會自動添加一個默認的無參構造
(3)如果一個類顯式/明確的聲明了構造器,那么編譯器將不再自動添加默認的無參構造,如果需要,那么就需要手動添加
(4)構造器的名稱必須與類名相同
(5)構造器沒有返回值類型
(6)構造器可以重載
示例代碼:
public class Circle{private double radius;public Circle(){}public Circle(double r){radius = r;//為radius賦值} }6.3 關鍵字this
1、this關鍵字:
意思:當前對象
(1)如果出現在構造器中:表示正在創建的對象
(2)如果出現在成員方法中:表示正在調用這個方法的對象
2、this的用法:
(1)this.屬性
當局部變量與成員變量同名時,那么可以在成員變量的而前面加“this.”用于區別
(2)this.方法
調用當前對象的成員方法,完全可以省略“this.”
(3)this()或this(實參列表)
this()表示調用本類的無參構造
this(實參列表)表示調用本類的有參構造
this()或this(實參列表)要么沒有,要么必須出現在構造器的首行
示例代碼:
public class Student{private String name;private int score;public Student(){}public Student(String name){this.name = name;}public Student(String name, int score){this(name);}public void setName(String name){this.name = name;}public String getName(){return name;}public void setScore(int score){this.score = score;}public int getScore(){return score;} }3、成員變量與局部變量的區別?
這里只討論實例變量(關于類變量見static部分)
(1)聲明的位置不同
成員變量:類中方法外
局部變量:方法中或代碼中
? ①方法的形參列表
? ②方法體中局部變量
? ③代碼塊中的局部變量
(2)運行時在內存中的存儲位置不同
成員變量:堆
局部變量:棧
基本數據類型的變量在棧中,引用數據類型的變量在堆中:不準確
(3)修飾符
成員變量:有很多修飾符,例如:權限修飾符
局部變量:不能加權限修飾符,唯一的能加的是final
(4)初始化
成員變量:有默認值
局部變量:沒有默認值,必須手動初始化
(5)生命周期
成員變量:隨著對象的創建而創建,隨著對象被回收而消亡,即與對象同生共死。每一個對象都是獨立的。
局部變量:方法調用時才分配,方法運行結束就沒有了。每一次方法調用,都是獨立的
6.4 包
1、包的作用:
(1)可以避免類重名
有了包之后,類的全名稱就變為:包.類名
(2)分類組織管理眾多的類
例如:java.lang包,java.util包,java.io包…
(3)可以控制某些類型或成員的可見范圍
如果某個類型或者成員的權限修飾缺省的話,那么就僅限于本包使用
2、聲明包的語法格式:
package 包名;注意:
(1)必須在源文件的代碼首行
(2)一個源文件只能有一個
3、包的命名規范和習慣:
(1)所有單詞都小寫,每一個單詞之間使用.分割
(2)習慣用公司的域名倒置
例如:com.atguigu.xxx;
建議大家取包名時不要使用“java.xx"包
4、使用其他包的類:
前提:被使用的類或成員的權限修飾符是>缺省的
(1)使用類型的全名稱
例如:java.util.Scanner input = new java.util.Scanner(System.in);
(2)使用import 語句之后,代碼中使用簡名稱
5、import語句
import 包.類名; import 包.*;注意:當使用兩個不同包的同名類時,例如:java.util.Date和java.sql.Date。
一個使用全名稱,一個使用簡名稱
示例代碼:
package com.atguigu.test;import java.util.Scanner;public class Test{public static void main(String[] args){Scanner input = new Scanner(System.in);} }6.5 eclipse的使用
1、eclipse管理項目和代碼的結構
workspace --> project --> 包–>類…
一個工作空間可以有多個項目。
2、快捷鍵
常規快捷鍵:
Ctrl + S:保存
Ctrl + C:復制
Ctrl + V:粘貼
Ctrl + X:剪切
Ctrl + Y:反撤銷
Ctrl + Z:撤銷
Ctrl + A:全選
eclipse中默認的快捷鍵:
Ctrl + 1:快速修復
Alt + /:代碼提示
Alt + ?: Alt + Shift + / 方法的形參列表提示
Ctrl + D:刪除選中行
Ctrl + Alt + ↓:向下復制行
Ctrl + Alt + ↑:向上復制行
Alt + ↓:與下面的行交換位置
Alt + ↑:與下面的行交換位置
Ctrl + Shift + F:快速格式
Ctrl + /:單行注釋,再按一次取消
Ctrl + Shift + /:多行注釋
Ctrl + Shift +\:取消多行注釋
Shift + 回車:在光標下一行插入新航開始編輯
Ctrl + Shift + 回車:在光標上一行插入新航開始編輯
Alt + Shift + A:多行編輯 再按一次退出多行編輯模式
Alt + Shift + S:彈出自動生成代碼的菜單選擇,包括自動生成構造器、get/set、equals…
Ctrl + Shift + O:快速導包
Ctrl + Shift + T:打開某個類的源文件
Ctrl + O:打開某個類型的摘要outline
3、快速開發的代碼模板
代碼模板 + Alt + /
(1)main
public static void main(String[] args){
}
(2)sysout
System.out.println();
(3)for
for(int i=0; i<數組名.lenght; i++){
}
其他詳細使用見《JavaSE_柴林燕_相關工具.docx》
6.6 面向對象的基本特征之二:繼承
1、為什么要繼承?繼承的好處?(理解)
(1)代碼的復用
(2)代碼的擴展
2、如何實現繼承?
語法格式:
【修飾符】 class 子類 extends 父類{}3、繼承的特點
(1)子類會繼承父類的所有特征(屬性、方法)
但是,私有的在子類中是不能直接使用的
(2)子類不會繼承父類的構造器
因為,父類的構造器是用于創建父類的對象的
(3)子類的構造器中又必須去調用父類的構造器
在創建子類對象的同時,為從父類繼承的屬性進行初始化用,可以借助父類的構造器中的代碼為屬性賦值。
(4)Java只支持單繼承:一個子類只能有一個“直接”父類
(5)Java又支持多層繼承:父類還可以有父類,特征會代代相傳
(6)一個父類可以同時擁有很多個子類
6.7 關鍵字super
super關鍵字:引用父類的,找父類的xx
用法:
(1)super.屬性
當子類聲明了和父類同名的成員變量時,那么如果要表示某個成員變量是父類的,那么可以加“super.”
(2)super.方法
當子類重寫了父類的方法,又需要在子類中調用父類被重寫的方法,可以使用"super."
(3)super()或super(實參列表)
super():表示調用父類的無參構造
super(實參列表):表示調用父類的有參構造
注意:
(1)如果要寫super()或super(實參列表),必須寫在子類構造器的首行
(2)如果子類的構造器中沒有寫:super()或super(實參列表),那么默認會有 super()
(3)如果父類沒有無參構造,那么在子類的構造器的首行“必須”寫super(實參列表)
6.8 方法的重寫
1、方法的重寫(Override)
當子類繼承了父類的方法時,又覺得父類的方法體的實現不適合于子類,那么子類可以選擇進行重寫。
2、方法的重寫的要求
(1)方法名:必須相同
(2)形參列表:必須相同
(3)修飾符
? 權限修飾符: >=
(4)返回值類型
? 如果是基本數據類型和void:必須相同
? 如果是引用數據類型:<=
? 在Java中我們認為,在概念范圍上:子類 <父類
3、重載(Overload)與重寫(Override)的區別
? 重載(Overload):在同一個類中,方法名相同,形參列表不同,和返回值類型無關的兩個或多個方法。
? 重寫(Override):在父子類之間。對方法簽名的要求見上面。
特殊的重載:
public class TestOverload {public static void main(String[] args) {B b = new B();//b對象可以調用幾個a方法b.a();b.a("");//從b對象同時擁有兩個方法名相同,形參不同的角度來說,算是重載} } class A{public void a(){//...} } class B extends A{public void a(String str){} }6.9 非靜態代碼塊
1、語法格式
【修飾符】 class 類名{{非靜態代碼塊} }2、作用
目的:在創建的過程中,為對象屬性賦值,協助完成實例初始化的過程
3、什么時候執行?
(1)每次創建對象時都會執行
(2)優先于構造器執行
6.10 實例初始化過程
1、概念描述
-
實例初始化過程:實例對象創建的過程
-
實例初始化方法:實例對象創建時要執行的方法
-
實例初始化方法的由來:它是有編譯器編譯生成的
-
實例初始化方法的形式:()或(形參列表)
-
實例初始化方法的構成:
①屬性的顯式賦值代碼
②非靜態代碼塊的代碼
③構造器的代碼
其中
①和②按順序執行,從上往下
③在①和②的后面
因此一個類有幾個構造器,就有幾個實例初始化方法。
2、單個類實例初始化方法
示例代碼:
class Demo{{System.out.println("非靜態代碼塊1");}private String str = assign();//調用方法,來為str進行顯式賦值public Demo(){System.out.println("無參構造");}public Demo(String str){this.str = str;System.out.println("有參構造");}{System.out.println("非靜態代碼塊2");}public String assign(){System.out.println("assign方法");return "hello";} }圖解:
3、父子類的實例初始化
注意:
(1)原先super()和super(實參列表)說是調用父類的構造器,現在就要糾正為調用父類的實例初始化方法了
(2)原先super()和super(實參列表)說是必須在子類構造器的首行,現在要糾正為必須在子類實例初始化方法的首行
結論:
(1)執行順序是先父類實例初始化方法,再子類實例初始化方法
(2)如果子類重寫了方法,通過子類對象調用,一定是執行重寫過的方法
示例代碼:
class Ba{private String str = assign();{System.out.println("(1)父類的非靜態代碼塊");}public Ba(){System.out.println("(2)父類的無參構造");}public String assign(){System.out.println("(3)父類的assign()");return "ba";} } class Er extends Ba{private String str = assign();{System.out.println("(4)子類的非靜態代碼塊");}public Er(){//super() ==>調用父類的實例初始化方法,而且它在子類實例初始化方法的首行System.out.println("(5)子類的無參構造");}public String assign(){System.out.println("(6)子類的assign()");return "er";} } class Test{public static void main(String[] args){new Er();//612645} }圖解:
6.11 面向對象的基本特征之三:多態
1、多態:
語法格式:
父類 引用/變量 = 子類的對象;2、前提:
(1)繼承
(2)方法的重寫
(3)多態引用
3、現象:
? 編譯時看左邊/“父類”,運行時看右邊/“子類”。
? 編譯時,因為按父類編譯,那么只能父類有的方法,子類擴展的方法是無法調用的;
? 執行時一定是運行子類重寫的過的方法體。
示例代碼:
class Person{public void eat(){System.out.println("吃飯");}public void walk(){System.out.println("走路");} } class Woman extends Person{public void eat(){System.out.println("細嚼慢咽的吃飯");}public void walk(){System.out.println("婀娜多姿走路");}public void shop(){System.out.println("買買買...");} } class Man extends Person{public void eat(){System.out.println("狼吞虎咽的吃飯");}public void walk(){System.out.println("大搖大擺的走路");}public void smoke(){System.out.println("吞云吐霧");} } class Test{public static void main(String[] args){Person p = new Woman();//多態引用p.eat();//執行子類重寫p.walk();//執行子類重寫//p.shop();//無法調用} }4、應用:
(1)多態參數:形參是父類,實參是子類對象
(2)多態數組:數組元素類型是父類,元素存儲的是子類對象
示例代碼:多態參數
class Test{public static void main(String[] args){test(new Woman());//實參是子類對象test(new Man());//實參是子類對象}public static void test(Person p){//形參是父類類型p.eat();p.walk();} }示例代碼:多態數組
class Test{public static void main(String[] args){Person[] arr = new Person[2];//多態數組arr[0] = new Woman();arr[1] = new Man();for(int i=0; i<arr.length; i++){all[i].eat();all[i].walk();}} }5、向上轉型與向下轉型:父子類之間的轉換
(1)向上轉型:自動類型轉換
? 當把子類的對象賦值給父類的變量時(即多態引用時),在編譯時,這個對象就向上轉型為父類。此時就看不見子類“特有、擴展”的方法。
(2)向下轉型:強制轉換。有風險,可能會報ClassCastException異常。
? 當需要把父類的變量賦值給一個子類的變量時,就需要向下轉型。
? 要想轉型成功,必須保證該變量中保存的對象的運行時類型是<=強轉的類型
示例代碼:
class Person{//方法代碼省略... } class Woman extends Person{//方法代碼省略... } class ChineseWoman extends Woman{//方法代碼省略... } public class Test{public static void main(String[] args){//向上轉型Person p1 = new Woman();//向下轉型Woman m = (Woman)p1; //p1變量中實際存儲的對象就是Woman類型,和強轉的Woman類型一樣//向上轉型Person p2 = new ChineseWoman();//向下轉型Woman w2 = (Woman) p2; //p2變量中實際存儲的對象是ChineseWoman類型,強制的類型是Woman,ChineseWoman<Woman類型 }}6、instanceof
表達式語法格式:
對象/變量 instanceof 類型運算結果:true 或 false
作用:
用來判斷這個對象是否屬于這個類型,或者說,是否是這個類型的對象或這個類型子類的對象
示例代碼:
class Person{//方法代碼省略... } class Woman extends Person{//方法代碼省略... } class ChineseWoman extends Woman{//方法代碼省略... } public class Test{public static void main(String[] args){Person p = new Person();Woman w = new Woman();ChineseWoman c = new ChineseWoman();if(p instanceof Woman){//false}if(w instanceof Woman){//true}if(c instanceof Woman){//true}}}總結
以上是生活随笔為你收集整理的零基础学java(6)——面向对象的基本特征的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序猿笑话集合
- 下一篇: 干货深挖!从写简历,到面试、谈薪酬的那些