欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java面向?qū)ο缶幊讨^承和多態(tài)以及包的解析與使用范例

 更新時(shí)間:2021年11月10日 09:50:32   作者:Unstoppedable  
繼承就是可以直接使用前輩的屬性和方法。自然界如果沒有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個(gè)接口,使用不同的實(shí)例而執(zhí)行不同操作

1.繼承

為什么要有繼承?
多個(gè)類中存在相同屬性和行為時(shí),將這些內(nèi)容抽取到單獨(dú)一個(gè)類中,
那么多個(gè)類無(wú)需再定義這些屬性和行為,只要繼承那個(gè)類即可。

此處的多個(gè)類稱為子類(派生類),單獨(dú)的這個(gè)類稱為父類(基類 或超類)??梢岳斫鉃?“子類 is a 父類”

1.1繼承的基本使用

類繼承語(yǔ)法規(guī)則:

class 子類 extends 父類{ }

繼承的作用:

  • 降低代碼的冗余度,提高代碼復(fù)用率
  • 繼承的出現(xiàn),更有利于功能的擴(kuò)展。
  • 繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系,提供了多態(tài)的前提

注意:

  • 子類不能直接訪問父類中私有的(private)的成員變量和方法
  • Java只支持單繼承和多層繼承,不允許多重繼承
  • 一個(gè)子類只能有一個(gè)父類一個(gè)父類可以派生出多個(gè)子類

如下代碼示例:

class Animal { 
    public String name; 
    public Animal(String name) { 
    this.name = name; 
    } 
    public void eat(String food) { 
    System.out.println(this.name + "正在吃" + food); 
    } 
} 
class Cat extends Animal { 
    public Cat(String name) { 
    // 使用 super 調(diào)用父類的構(gòu)造方法. 
    super(name); 
    } 
} 
class Bird extends Animal { 
    public Bird(String name) {
    super(name); 
    } 
    public void fly() { 
    System.out.println(this.name + "正在飛 ︿( ̄︶ ̄)︿"); 
    } 
} 
public class Test { 
    public static void main(String[] args) { 
    Cat cat = new Cat("小黑"); 
    cat.eat("貓糧"); 
    Bird bird = new Bird("圓圓"); 
    bird.fly(); 
    } 
}

1.2 protected 關(guān)鍵字

剛才我們發(fā)現(xiàn), 如果把字段設(shè)為 private, 子類不能訪問. 但是設(shè)成 public, 又違背了我們 “封裝” 的初衷.
兩全其美的辦法就是 protected 關(guān)鍵字.

  • 對(duì)于類的調(diào)用者來說, protected 修飾的字段和方法是不能訪問的
  • 對(duì)于類的 子類 和 同一個(gè)包的其他類 來說, protected 修飾的字段和方法是可以訪問的

四種權(quán)限修飾符:

四種權(quán)限修飾

1.3 final 關(guān)鍵字

曾經(jīng)我們學(xué)習(xí)過 final 關(guān)鍵字, 修飾一個(gè)變量或者字段的時(shí)候, 表示 常量 (不能修改).

final int a = 10; 
a = 20; // 編譯出錯(cuò)

final 關(guān)鍵字也能修飾類, 此時(shí)表示被修飾的類就不能被繼承

final public class Animal { 
 ... 
} 
public class Bird extends Animal { 
 ... 
} 
// 編譯出錯(cuò)
Error:(3, 27) java: 無(wú)法從最終com.bit.Animal進(jìn)行繼承

final 關(guān)鍵字的功能是 限制 類被繼承。我們平時(shí)使用的String字符串類,就是被final修飾的,不能被繼承。

2.多態(tài)

2.1向上轉(zhuǎn)型

在剛才的例子中, 我們寫了形如下面的代碼:

Bird bird = new Bird("圓圓"); 

這個(gè)代碼也可以寫成這個(gè)樣子

Bird bird = new Bird("圓圓"); 
Animal bird2 = bird; 
// 或者寫成下面的方式
Animal bird2 = new Bird("圓圓"); 

此時(shí) bird2 是一個(gè)父類 (Animal) 的引用, 指向一個(gè)子類 (Bird) 的實(shí)例. 這種寫法稱為 向上轉(zhuǎn)型.

向上轉(zhuǎn)型是子類對(duì)象轉(zhuǎn)成父類對(duì)象

向上轉(zhuǎn)型發(fā)生的時(shí)機(jī):

  • 直接賦值
  • 方法傳參
  • 方法返回

直接賦值的方式我們已經(jīng)演示了. 另外兩種方式和直接賦值沒有本質(zhì)區(qū)別

方法傳參

代碼示例:

public class Test { 
    public static void main(String[] args) { 
    Bird bird = new Bird("圓圓"); 
    feed(bird); 
    } 
    public static void feed(Animal animal) { 
    animal.eat("谷子"); 
    } 
} 
// 執(zhí)行結(jié)果
圓圓正在吃谷子

此時(shí)形參 animal 的類型是 Animal (基類), 實(shí)際上對(duì)應(yīng)到 Bird (父類) 的實(shí)例.

方法返回

代碼示例

public class Test { 
   public static void main(String[] args) { 
   Animal animal = findMyAnimal(); 
   } 
   public static Animal findMyAnimal() { 
   Bird bird = new Bird("圓圓"); 
   return bird; 
   } 
}

此時(shí)方法 findMyAnimal 返回的是一個(gè) Animal 類型的引用, 但是實(shí)際上對(duì)應(yīng)到 Bird 的實(shí)例

2.2動(dòng)態(tài)綁定

當(dāng)子類和父類中出現(xiàn)同名方法的時(shí)候, 再去調(diào)用會(huì)出現(xiàn)什么情況呢?

對(duì)前面的代碼稍加修改, 給 Bird 類也加上同名的 eat 方法, 并且在兩個(gè) eat 中分別加上不同的日志.

如下:

// Animal.java 
public class Animal { 
 protected String name; 
 public Animal(String name) { 
 this.name = name; 
 } 
 public void eat(String food) { 
 System.out.println("我是一只小動(dòng)物"); 
 System.out.println(this.name + "正在吃" + food); 
 }
} 
// Bird.java 
public class Bird extends Animal { 
 public Bird(String name) { 
 super(name); 
 } 
 public void eat(String food) { 
 System.out.println("我是一只小鳥"); 
 System.out.println(this.name + "正在吃" + food); 
 } 
} 
// Test.java 
public class Test { 
 public static void main(String[] args) { 
 Animal animal1 = new Animal("圓圓"); 
 animal1.eat("谷子"); 
 Animal animal2 = new Bird("扁扁"); 
 animal2.eat("谷子"); 
 } 
} 

// 執(zhí)行結(jié)果
我是一只小動(dòng)物
圓圓正在吃谷子
我是一只小鳥
扁扁正在吃谷子

此時(shí), 我們發(fā)現(xiàn):

  • animal1 和 animal2 雖然都是 Animal 類型的引用, 但是 animal1 指向 Animal 類型的實(shí)例, animal2 指向Bird 類型的實(shí)例.
  • 針對(duì) animal1 和 animal2 分別調(diào)用 eat 方法, 發(fā)現(xiàn) animal1.eat() 實(shí)際調(diào)用了父類的方法, 而animal2.eat() 實(shí)際調(diào)用了子類的方法.

因此, 在 Java 中, 調(diào)用某個(gè)類的方法, 究竟執(zhí)行了哪段代碼 (是父類方法的代碼還是子類方法的代碼) , 要看究竟這個(gè)引
用指向的是父類對(duì)象還是子類對(duì)象. 這個(gè)過程是程序運(yùn)行時(shí)決定的(而不是編譯期), 因此稱為 動(dòng)態(tài)綁定

2.3方法重寫

定義:在子類中可以根據(jù)需要對(duì)從父類中繼承來的方法進(jìn)行改造,也稱
為方法的重置、覆蓋。在程序執(zhí)行時(shí),子類的方法將覆蓋父類的方法。

要求:

  • 子類重寫的方法必須和父類被重寫的方法具有相同的方法名稱、參數(shù)列表
  • 子類重寫的方法的返回值類型不能大于父類被重寫的方法的返回值類型
  • 子類重寫的方法使用的訪問權(quán)限不能小于父類被重寫的方法的訪問權(quán)限,子類不能重寫父類中聲明為private權(quán)限的方法
  • 子類方法拋出的異常不能大于父類被重寫方法的異常

注意:
子類與父類中同名同參數(shù)的方法必須同時(shí)聲明為非static的(即為重寫),或者同時(shí)聲明為static的(不是重寫)。因?yàn)閟tatic方法是屬于類的,子類無(wú)法覆蓋父類的方法

方法重寫舉例1:

public class Person {
    public String name;
    public int age;
    public String getInfo() {
    return "Name: "+ name + "\n" +"age: "+ age;
    } 
}
public class Student extends Person {
    public String school;
    public String getInfo() { //重寫方法
    return "Name: "+ name + "\nage: "+ age 
    + "\nschool: "+ school;
}
public static void main(String args[]){
    Student s1=new Student();
    s1.name="Bob";
    s1.age=20;
    s1.school="school2";
    System.out.println(s1.getInfo()); //Name:Bob age:20 school:school2
    } 
}

方法重寫舉例2:

class Parent {
    public void method1() {}
}
class Child extends Parent {
    //非法,子類中的method1()的訪問權(quán)限private比被覆蓋方法的訪問權(quán)限public小
    private void method1() {} 
}
public class UseBoth {
    public static void main(String[] args) {
    Parent p1 = new Parent();
    Child c1 = new Child();
    p1.method1();
    c1.method1();
    }
}

2.4向下轉(zhuǎn)型

向下轉(zhuǎn)型就是父類對(duì)象轉(zhuǎn)成子類對(duì)象. 相比于向上轉(zhuǎn)型來說, 向下轉(zhuǎn)型沒那么常見,
但是也有一定的用途.

  • 從子類到父類的類型轉(zhuǎn)換可以自動(dòng)進(jìn)行
  • 從父類到子類的類型轉(zhuǎn)換必須通過造型(強(qiáng)制類型轉(zhuǎn)換)實(shí)現(xiàn)
  • 無(wú)繼承關(guān)系的引用類型間的轉(zhuǎn)換是非法的
  • 在造型前可以使用instanceof操作符測(cè)試一個(gè)對(duì)象的類型

對(duì)于 Animal animal = new Bird(“圓圓”) 這樣的代碼:

編譯器檢查有哪些方法存在, 看的是 Animal 這個(gè)類型

執(zhí)行時(shí)究竟執(zhí)行父類的方法還是子類的方法, 看的是 Bird 這個(gè)類型.

那么想實(shí)現(xiàn)剛才的效果, 就需要向下轉(zhuǎn)型.

// (Bird) 表示強(qiáng)制類型轉(zhuǎn)換
Bird bird = (Bird)animal; 
bird.fly(); 
// 執(zhí)行結(jié)果
圓圓正在飛

為了讓向下轉(zhuǎn)型更安全, 我們可以先判定一下看看 animal 本質(zhì)上是不是一個(gè) Bird 實(shí)例, 再來轉(zhuǎn)換

Animal animal = new Cat("小貓"); 
if (animal instanceof Bird) { 
 Bird bird = (Bird)animal; 
 bird.fly(); 
}

instanceof 可以判定一個(gè)引用是否是某個(gè)類的實(shí)例. 如果是,則返回 ture。 這時(shí)再進(jìn)行向下轉(zhuǎn)型就比較安全了。

2.5super 關(guān)鍵字

2.5.1 super 關(guān)鍵字的基本用法

在Java類中使用super來調(diào)用父類中的指定操作:

  • super可用于訪問父類中定義的屬性
  • super可用于調(diào)用父類中定義的成員方法
  • super可用于在子類構(gòu)造器中調(diào)用父類的構(gòu)造器

注意:

  • 尤其當(dāng)子父類出現(xiàn)同名成員時(shí),可以用super表明調(diào)用的是父類中的成員  super的追溯不僅限于直接父類
  • super和this的用法相像,this代表本類對(duì)象的引用,super代表父類的內(nèi)存

空間的標(biāo)識(shí)

示例1使用了 super 來調(diào)用父類的構(gòu)造器(這個(gè)代碼前面已經(jīng)寫過了)

public Bird(String name) { 
 super(name); 
} 

示例2使用 super 來調(diào)用父類的普通方法

public class Bird extends Animal { 
 public Bird(String name) { 
 super(name); 
 } 
 @Override 
 public void eat(String food) { 
 // 修改代碼, 讓子調(diào)用父類的接口. 
 super.eat(food); 
 System.out.println("我是一只小鳥"); 
 System.out.println(this.name + "正在吃" + food); 
 } 
}

2.5.2 this和super的區(qū)別

this 和 super 的區(qū)別

3.包的使用

包 (package) 是組織類的一種方式.
使用包的主要目的是保證類的唯一性.
例如, 你在代碼中寫了一個(gè) Test 類. 然后你的同事也可能寫一個(gè) Test 類. 如果出現(xiàn)兩個(gè)同名的類, 就會(huì)沖突, 導(dǎo)致代碼不能編譯通過

3.1導(dǎo)入包中的類

包 (package) 是組織類的一種方式.
使用包的主要目的是保證類的唯一性
代碼示例:

public class Test {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        // 得到一個(gè)毫秒級(jí)別的時(shí)間戳
        System.out.println(date.getTime());
   }
}

可以使用 import 語(yǔ)句導(dǎo)入包

import java.util.Date;
public class Test {
    public static void main(String[] args) {
        Date date = new Date();
        // 得到一個(gè)毫秒級(jí)別的時(shí)間戳
        System.out.println(date.getTime());
   }
}

如果需要使用 java.util 中的其他類, 可以使用 import java.util.*

注意:Java是用到包中的那個(gè)類就導(dǎo)入那個(gè)類

但是我們更建議顯式的指定要導(dǎo)入的類名. 否則還是容易出現(xiàn)沖突的情況.
例如:

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        // util 和 sql 中都存在一個(gè) Date 這樣的類, 此時(shí)就會(huì)出現(xiàn)歧義, 編譯出錯(cuò)
        Date date = new Date();
        System.out.println(date.getTime());
   }
}
// 編譯出錯(cuò)

在這種情況下我們就需要完整的包名

import static java.lang.Math.*;
public class Test {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
        // 靜態(tài)導(dǎo)入的方式寫起來更方便一些.但不推薦
        // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        double result = sqrt(pow(x, 2) + pow(y, 2));
        System.out.println(result);
   }
}

3.2常見系統(tǒng)包

  • java.lang:系統(tǒng)常用基礎(chǔ)類(String、Object),此包從JDK1.1后自動(dòng)導(dǎo)入。
  • java.lang.reflect:java 反射編程包;
  • java.net:進(jìn)行網(wǎng)絡(luò)編程開發(fā)包。
  • java.sql:進(jìn)行數(shù)據(jù)庫(kù)開發(fā)的支持包。
  • java.util:是java提供的工具程序包。(集合類等) 非常重要
  • java.io:I/O編程開發(fā)包

以上就是Java面向?qū)ο缶幊讨^承和多態(tài)以及包的解析與使用范例的詳細(xì)內(nèi)容,更多關(guān)于Java 繼承和多態(tài) 的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論