Java入門——(3)面對對象(下)

關鍵詞:  類的繼承、final關鍵字、多態、接口、異常、包、訪問控制
1、類的繼承
      一、類的繼承是指在一個現有類的基礎上去構建一個新的類,構建出來的新類被稱做子類,現有類被稱做父類,子類會自動擁有父類全部可繼承的屬性和方法,使用 extends關鍵字。
 
class A{}
class B extends A{}

 

       在Java中繼承的體現:
       ①Java容許單繼承。不直接支持多繼承,將多繼承進行其餘方式的體現。
       ②單繼承:一個子類只能有一個父類。
class A{}
class B{}
class C extends A,B{}  //C類不能夠同時繼承A類和B類
       ③多繼承:一個子類能夠有多個父類,用多實現體現。
       ④多重繼承,繼承體系。
       學習繼承體系時,應該參閱頂層的類中的內容,瞭解這個體系的基本功能。使用這個體系功能,須要建立最子類的對象。(看頂層,建底層。)
 
      二、override:子父類中的定義瞭如出一轍的函數。運行的結果:子類的函數在運行。這種狀況在子父類中,是函數的另外一個特性:override(重寫、覆蓋、複寫)。
      重寫的注意事項:

      ①子類覆蓋父類,必須保證權限要大於或等於父類的權限。html

      ②靜態覆蓋靜態。java

      ③寫法上必須如出一轍,函數的返回值類型 函數名 參數列表都要同樣。編程

       三、super關鍵字網絡

       ①子父類中構造函數的特色:
       當子父類都有構造函數時,先執行父類的構造函數,再執行子類的構造函數,由於子類的全部的構造函數中的第一行都有一句隱式語句
       super();//默認調用的是父類中的空參數的構造函數。
 
       爲何子類中的構造函數有一句隱式的super()?
       緣由:子類會繼承父類中的內容,因此子類在初始化時,必須先到父類中去執行父類的初始化動做。才能夠更方便使用父類中的內容。
       當父類中沒有空參數構造函數時,子類的構造函數必須同構顯式的super語句指定要訪問父類中的構造函數。
       細節:

①若是子類的構造函數第一行寫了this調用了背離其餘構造函數,那麼super調用父類的語句是沒有的,由於this()或者super(),只能在構造函數的第一行,由於初始化動做要先執行。jvm

②父類構造函數中是否有隱式的super呢?也是有的,只要是構造函數默認第一行都是super();ide

父類的父類是誰?super調用的究竟是誰的構造函數,在Java體系在設計,定義了一個全部對象的父類object。
總結:類中的構造函數默認第一行都有隱式的super()語句,在訪問父類中的構造函數。
因此父類的構造函數既能夠給本身對象初始化,也能夠給本身的子類對象初始化。
若是默認的隱式super的語句沒有對應的構造函數,必須在構造函數中經過this後者super的形式明確調用的構造函數。
 
super應用:
①子類的實例化過程的應用,也是super調用的應用。

②只要使用父類的指定初始化動做,就在子類中經過super(參數列表)格式進行調用。函數

super關鍵字的用法:

①使用super關鍵字調用父類的成員變量和成員方法。具體格式:工具

super.成員變量
super.成員方法([參數1,參數2……….])

②使用super關鍵字調用父類的構造方法,具體格式:post

super([參數1,參數2……….])
經過super調用父類構造方法的代碼必須位於子類構造方法的第一行,且只能出現一次。
      在定義一個類時,若是沒有特殊需求,儘可能在類中定義一個無參的構造方法,避免繼承時出現錯誤。
 
      繼承的弊端:打破封裝性。
 
2、final關鍵字
 
      一、final(最終化)修飾符,能夠修飾類、方法、變量(成員變量、局部變量、靜態變量)。

      ①final修飾的類是一個最終類,該類將不能被繼承,不能派生子類。學習

      ②final 修飾的方法是最終方法,不能夠重寫。
      當父類中定義某個方法時,若是不但願被子類重寫,就可使用final關鍵字修飾該方法。
      如:public final void shout(){}

③final修飾的變量是一個常量,只能被賦值一個。

 如:final int num = 2;

二、【何時會在程序中定義final常量呢?】
當程序中一個數據使用時是固定不變的,這時爲了增長閱讀性,能夠給該數據起個名字。
這是變量,爲了保證這個變量的值不被修改,加上final修飾,這是一個閱讀性很強的常量。
書寫規範,被final修飾的常量名全部字母都是大寫的。若是由多個單詞間經過 _ 鏈接。
 
3、抽象類和接口
一、abstract(抽象)
抽象類:在描述事物時,沒有足夠的信息描述一個事物,這時該事物就是抽象事物。
定義了抽象函數的類,也必須被abstract關鍵字修飾,被abstract關鍵字修飾的類是抽象類。
抽象方法的類必須聲明爲抽象類,但抽象類能夠不包含任何抽象方法,只要abstract關鍵字修飾便可。
 
【抽象類的特色】

        ①抽象類和抽象方法都須要被abstract修飾。(抽象方法必定要定義在抽象類中)。

//定義抽象類Animal
abstract class Animal{
//定義抽象方法shuot()
abstract int shout ();
}

       ②抽象類不能夠建立實例,緣由:調用抽象方法沒有方法體。

       ③只要覆蓋了抽象類中全部的抽象方法後,其子類才能夠實例化。不然該子類仍是一個抽象類。

       之因此繼承,更多的是在思想,是面對共性類型操做會更簡單。
 
    二、接口(interface)
    接口:若是一個類中的全部抽象方法都是抽象的,則能夠將這個類用另一種方式來定義,即接口。在定義接口時,須要使用interface關鍵字來聲明,如:
1 interface Animal{
2     int ID = 1; //定義全局變量
3     void breathe(); //定義抽象方法
4     void run ();
5 } // Animal 即爲一個接口,接口中定義的的方法和變量都包含一些默認修飾符「public abstract」(抽象方法)「public static final」(全局變量)。
 
      接口的特色:

①接口能夠建立對象;

②子類必須覆蓋掉接口中全部的抽象方法後,子類才能夠實例化。不然子類是一個抽象類。

③實現多接口示例:

複製代碼
interface Run{
程序代碼…..
}
interface Fly{
程序代碼…..
}
class Bird implements Run,Fly{
程序代碼…….
}
複製代碼
       定義子類去覆蓋接口的方法:子類必須和接口產生關係,類與類的關係是繼承,類與接口之間的關係是實現,經過關鍵字implements 。
 
接口最重要的體現:解決多繼承的弊端。將多繼承這種機制在Java中經過多實現完成。
多繼承的弊端:當多個父類中有相同功能時,子類調用會產生不肯定性。
其核心緣由就是在於多繼承父類中功能有主體,而致使調用運行時,不肯定運行哪一個主體內容。
接口中的功能都沒有方法體,由子類來明確。
 
       若是子類想要繼承擴展其餘類中的功能,可經過接口實現:
class Dog extends Canidae implements Animal{ //先繼承,再實現
程序代碼……
}
       父類定義事物的基本功能,接口定義事物的擴展功能。
 
       接口出現後的一些細節:類與類之間是繼承關係,類與接口是實現關係;接口與接口之間是繼承關係,並且能夠多繼承。
 
4、多態
一、多態的概述
【體現】
父類的引用或者接口的引用指向了本身的子類對象。
Dog d = new Dog(); // Dog對象的類型是Dog類型
Animal a = new Dog(); // Dog對象的類型右邊是Dog類型,左邊Animal 類型。
【好處】
提升了程序的擴展性。
【弊端】
經過父類引用操做子類對象時,只能使用父類中已有的方法,不能操做子類特有的方法。
【前提】
①必須有關係,繼承、實現。
②一般都有重寫操做。
複製代碼
 1 //定義接口Animal
 2 interface Animal{
 3     void shout();
 4 }
 5 //定義Cat類實現Animal接口
 6 class Cat implements Animal{
 7        //實現shout()方法
 8     public void shout(){
 9         System.out.println("喵喵...");
10     }
11 }
12 //定義Dog類型實現Animal接口
13 class Dog implements Animal{
14     public void shout(){
15         System.out.println("汪汪");
16     }
17 }
18 //定義測試類
19 public class Example13 {
20     public static void main(String[] args) {
21         Animal an1 =new Cat();//建立Cat對象,使用Animal類型的變量an1引用
22         Animal an2 =new Dog();//建立Dog對象,使用Animal類型的變量an2引用
23         animalShout(an1);     //調用animalShout()方法,將an1做爲參數傳入
24         animalShout(an2);     //調用animalShout()方法,將an2做爲參數傳入
25     }
26     public static void animalShout(Animal an) {
27         an.shout();
28     }
29 }
複製代碼

運行結果

喵喵…
汪汪
【子類的特有方法如何調用?】
Animal a = new Dog();//Animal是父類型,new Dog()子對象。
可是父類型引用指向子類對象時,這就是讓子類對象進行了類型的提高(向上轉型)。
向上轉型好處:提升了擴展性,隱藏了子類型。
弊端:不能使用子類型的特有方法。
若是想使用子類的特有方法,只有子類型能夠用。
能夠向下轉型,強制轉換。
Animal a = new Dog();
a.eat();
Dog d = (Dog)a; //將a轉型爲Dog 類型。向下轉型。
d.lookHome();
向下轉型何時用?當須要使用子類型的特有內容時。
注意:不管向上仍是向下轉型,最終都是子類對象作着類型的變化。
【向下轉型的注意事項】
Animal a = new Dog();
Cat c = (Cat)a;//向下轉型由於不明確具體子類對象類型,因此容易引起classCastException(轉型異常)異常。
因此爲了不這個問題,須要在向下轉型前,作類型的判斷。
判斷類型用的是關鍵字 instanceof
複製代碼
if(a instanceof Cat){   //a指向的對象的類型是Cat類型。
    //將a轉型Cat 類型。
    Cat c = (Cat)a;
    c.catchMouse();
}else if(a instanceof Dog){
    Dog d = (Dog) a;
    d.lookHome();
}
複製代碼
示例:
複製代碼
 1 interface Animal{
 2     void shout();//定義抽象方法shout()
 3 }
 4 //定義Cat類實現Animal接口
 5 class Cat implements Animal{
 6     //實現抽象方法shout()
 7     public void shout(){
 8         System.out.println("喵喵...");
 9     }
10     //定義sleep()方法
11     public void sleep(){
12         System.out.println("貓在睡覺.....");
13     }
14 }
15 //定義Dog類實現Animal接口
16 class Dog implements Animal{
17     //實現抽象方法shout()
18     public void shout(){
19         System.out.println("汪汪...");
20     }
21 }
22 //定義測試類
23 public class Example14 {
24     public static void main(String[] args) {
25         Animal dog = new Dog();    //建立Dog類的實例對象
26         animalShout(dog);    //調用animalShout()方法,將dog做爲參數傳入
27     }
28     public static void animalShout(Animal animal) {
29         if (animal instanceof Cat) {
30             Cat cat = (Cat) animal;//將animal對象強制裝換爲Cat類型
31             cat.shout();           //調用cat的shout()方法
32             cat.sleep();           //調用cat的sleep()方法
33         }else{
34             System.out.println("this animal is not a cat!");
35         }
36     }
37 }
複製代碼

 運行結果:

this animal is not a cat!
【轉型總結】

①何時向上轉型?

提升程序的擴展性,不關係子類類型(子類型被隱藏)。
須要用子類的特有方法嗎?不須要,向上轉型。

②何時向下轉型?

須要使用子類型的特有方法時。
可是必定要使用instanceof 進行類型的判斷。避免發生classCastException。
 
二、匿名內部類格式:
new 父類(參數列表)或父接口(){
// 匿名內部類實現部分
}

示例

複製代碼
 1 interface Animal{
 2     void shout();
 3 }
 4 public class Example18 {
 5     public static void main(String[] args) {
 6         animalShout(new Animal(){
 7             public void shout() {
 8                 System.out.println("喵喵...");
 9             }
10         });
11     }
12     public static void animalShout(Animal an) {
13         an.shout();
14     }
15 }
複製代碼

運行結果

喵喵... 
     
     三、Object類是全部類的根類,定義了全部對象都具有的功能,通常狀況下均會重寫Object的toString()方法,來返回指定的信息。
     示例:
複製代碼
 1 class Animal{
 2     /*//定義動物叫的方法
 3     void shout(){
 4         System.out.println("動物叫");
 5     }*/
 6     //重寫Object類中的toString()方法
 7 
 8     @Override
 9     public String toString() {
10         return "I am an animal!";
11     }
12 }
13 //定義測試類
14 public class Example16 {
15     public static void main(String[] args) {
16         Animal animal = new Animal();       //建立Animal類對象
17         System.out.println(animal.toString()); //調用toString()方法並打印
18     }
19 }
複製代碼

5、異常

       一、Throwable類的繼承體系

      

       
 
①錯誤類(Error類):表示Java運行時產生的系統內部錯誤或資源耗盡的錯誤,是比較嚴重的,僅靠修改程序自己是不能恢復執行的。
②運行時異常與編譯時異常:
     編譯時異常:在Java中Exception類中除了RuntimeException類即其子類都是編譯時異常。特色是編譯器會檢測的異常,若是出現異常就必須對異常進行處理,不然程序沒法經過編譯。

     運行時異常:RuntimeException類即其子類都是運行時異常,編譯器不會檢測的異常,不須要聲明。

        ③Throwable經常使用方法
Throwable經常使用方法
方法聲明 功能描述
String getMessage() 返回此throwable的詳細消息字符串
void printStackTrace() 將此throwable及其追蹤輸出至標準錯誤流
void printStackTrace(PrintStream s) 將此throwable及其追蹤輸出至指定的輸出流
二、try...catch和finally
異常捕獲:Java中對異常有針對性的語句進行捕獲。
語句:
try{
      //須要被檢測的語句
}catch(ExceptionType(Exception類及其子類) e) {
      //ExceptionType的處理
}
發生異常後繼續執行一段程序
finally{
    //必定會被執行的語句
}

示例

複製代碼
 1 public class Example20 {
 2     public static void main(String[] args) {
 3        // 下面的代碼定義了一個try...catch語句用於捕捉異常
 4         try {
 5              int result = divide(4,0);  //調用divide()方法
 6              System.out.println(result);
 7         } catch (Exception e) {      //對異常進行處理
 8             System.out.println("捕捉的異常信息爲" + e.getMessage());
 9             return;    //用於結束當前語句
10         }finally {
11             System.out.println("進入finally代碼塊」);
12         }
13        System.out.println("程序繼續向下執行...");
14     }
15         //下面的方法實現了兩個整數相除
16         public static int divide(int x,int y) {
17             int result = x/y;   //定義一個變量result記錄兩個整數相除的結果
18             return result;      //將結果返回
19         }
20 }
複製代碼

運行結果

捕獲的異常信息是:/by zero
進入代碼塊

在程序設計時,常常會在try...catch後使用finally代碼塊來完成必須作的事情,例如釋放系統資源。需注意,當try...catch中執行了System.exit(0)語句,則退出Java虛擬機,任何代碼都不能繼續執行。

try catch finally 組合方式:

①try catch :對代碼進行異常檢測,並對檢測的異常傳遞給catch處理。

       異常捕獲處理。
Void show ()throws {//不須要throws
    try{
         throw new Exception();
    }finally{
    }
}

 

②try finally:對代碼進行異常檢測,檢測到異常後由於沒有catch,因此同樣會被默認jvm拋出。

      異常是沒有捕獲處理的,可是功能所開啓資源須要進行關閉,全部finally只爲關閉資源。
Void show () {//須要throws
    try{
         throw new Exception();
    }finally{
    }
}

③try catch finally

       檢測異常,並傳遞給catch 處理,並定義資源釋放。

④try catch1 catch2 catch3………

三、throws關鍵字
①throws關鍵字聲明拋出異常的語法格式以下:
   修飾符 返回值類型 方法名([參數1,參數2…])throws ExceptionType1[,ExceptionType2….]{
    }
② 聲明:將問題標識出來,報告給調用者。
   格式:
void show ()throws Exception{
     throw new Exception();
}
        若是函數內經過throw拋出了編譯時異常,捕獲,那麼必須經過throws進行聲明,讓調用者去處理。
 
四、自定義異常格式:
throw Exception 異常對象
       示例
複製代碼
 1 class DivideByMinusException extends Exception{
 2         public DivideByMinusException(){
 3             super();//調用Exception無參的構造方法
 4         }
 5         public DivideByMinusException(String message){
 6             super(message);//調用Exception無參的構造方法
 7         }
 8 }
 9 public class Example26 {
10     public static void main(String[] args) {
11         try{
12             int result = divide(4,-2);
13             System.out.println(result);
14         }catch (DivideByMinusException e){
15             System.out.println(e.getMessage());
16         }
17     }
18     public static int divide(int x,int y)throws DivideByMinusException{
19         if(y<0){
20             throw new DivideByMinusException("被除數是負數");
21         }
22         int result = x/y ;
23         return result;
24     }
25 } 
複製代碼
 
6、包的定義與使用
一、Java 中的包是專門用來存放類的,一般功能相同的類存放在相同的包中。
如: 
1 package cn.itcast.chapter04; 
2 public class Example01 {….} 
包的聲明只能位於Java源文件的第一行
二、包的導入
import 包名.類名;
      三、經常使用的包
       ①java.lang:包含Java語言的核心類,如String、Math、System和Thread類等,使用這個包中的類無需使用import語句導入,系統會自動導入這個包下的全部類。
       ②java.util: 包含Java中大量工具類、集合類等,例如Arrays、List、Set等。
       ③java.net:包含Java網絡編程相關的類和接口。
       ④java.io:包含了Java輸入、輸出有關的類和接口。
 
7、訪問權限修飾符權限:

訪問控制級別

 

同一類中

同一包下

(有無關係都可)

不一樣包下(子類)

不一樣包下

(沒有關係)

private

Y

     

default(默認)

Y

Y

   

protected

Y

Y

Y

 

public

Y

Y

Y

Y

 
相關文章
相關標籤/搜索