導航🚀
- 包
- 匯入包中的類
- 靜態匯入
- 將類放到包中
- 包的訪問權限
- 常見的系統包
- 繼承
- 背景
- 語法規則
- protected 關鍵字
- final 關鍵字
包
包 (package) 是組織類的一種方式.
使用包的主要目的是保證類的唯一性.
例如, 你在代碼中寫了一個 Test 類. 然后你的同事也可能寫一個 Test 類. 如果出現兩個同名的類, 就會沖突, 導致代碼不能編譯通過.
匯入包中的類
Java 中已經提供了很多現成的類供我們使用. 例如
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到一個毫秒級別的時間戳
System.out.println(date.getTime());
}
}
可以使用java.util.Date 這種方式引入 java.util 這個包中的 Date 類,
但是這種寫法比較麻煩一些, 可以使用import 陳述句匯入包.
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一個毫秒級別的時間戳
System.out.println(date.getTime());
}
}
如果需要使用java.util 中的其他類, 可以使用 import java.util.*
import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一個毫秒級別的時間戳
System.out.println(date.getTime());
}
}
但是我們更建議顯式的指定要匯入的類名. 否則還是容易出現沖突的情況.
import java.util.*;
import java.sql.*;
public class Test {
public static void main(String[] args) {
// util 和 sql 中都存在一個 Date 這樣的類, 此時就會出現歧義, 編譯出錯
Date date = new Date();
System.out.println(date.getTime());
}
}
Error:(5, 9) java: 對Date的參考不明確
java.sql 中的類 java.sql.Date 和 java.util 中的類 java.util.Date 都匹配
在這種情況下需要使用完整的類名
import java.util.*;
import java.sql.*;
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
System.out.println(date.getTime());
}
}
注意事項: import 和 C++ 的 #include 差別很大. C++ 必須 #include 來引入其他檔案內容, 但是 Java 不需要.
import只是為了寫代碼的時候更方便. import 更類似于 C++ 的 namespace 和 using
靜態匯入
使用import static 可以匯入包中的靜態的方法和欄位.
import static java.lang.System.*;
public class Test {
public static void main(String[] args) {
out.println("hello");
}
}
使用這種方式可以更方便的寫一些代碼, 例如
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 靜態匯入的方式寫起來更方便一些.
// 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);
}
}
將類放到包中
基本規則
1、在檔案的最上方加上一個 package 陳述句指定該代碼在哪個包中.
2、包名需要盡量指定成唯一的名字, 通常會用公司的域名的顛倒形式(例如com.bit.demo1).
3、包名要和代碼路徑相匹配. 例如創建 com.bit.demo1的包, 那么會存在一個對應的路徑 com/bit/demo1 來存盤代碼.
3、如果一個類沒有 package 陳述句, 則該類被放到一個默認包中.

上面的流程就是我們在com.bit.demo1新建了了Main類,
包的訪問權限
我們已經了解了類中的 public 和 private. private 中的成員只能被類的內部使用.
如果某個成員不包含 public 和 private 關鍵字, 此時這個成員可以在包內部的其他類使用, 但是不能在包外部的類使用.
下面的代碼給了一個示例. Demo1 和 Demo2 是同一個包中, Main 是其他包中.
package com.bit.demo1;
public class Demo1 {
int value = 0;
}
package com.bit.demo1;
public class Demo2 {
public static void Main(String[] args) {
Demo1 demo = new Demo1();
System.out.println(demo.value);
}
}
import com.bit.demo1.Demo1;
public class Main {
public static void main(String[] args) {
Demo1 demo = new Demo1();
System.out.println(demo.value);
}
}

常見的系統包
常見的系統包
- java.lang:系統常用基礎類(String、Object),此包從JDK1.1后自動匯入,
- java.lang.reflect:java 反射編程包;
- java.net:進行網路編程開發包,
- java.sql:進行資料庫開發的支持包,
- java.util:是java提供的工具程式包,(集合類等) 非常重要
- java.io:I/O編程開發包,
繼承
背景
代碼中創建的類, 主要是為了抽象現實中的一些事物(包含屬性和方法).
有的時候客觀事物之間就存在一些關聯關系, 那么在表示成類和物件的時候也會存在一定的關聯.
例如, 設計一個類表示動物
注意, 我們可以給每個類創建一個單獨的 java 檔案. 類名必須和 .java 檔案名匹配(大小寫敏感).
// Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Cat.java
class Cat {
public String name;
public Cat(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Bird.java
class Bird {
public String name;
public Bird(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
public void fly() {
System.out.println(this.name + "正在飛 ︿( ̄︶ ̄)︿");
}
}
這個代碼我們發現其中存在了大量的冗余代碼.
仔細分析, 我們發現 Animal 和 Cat 以及 Bird 這幾個類中存在一定的關聯關系:
1、這三個類都具備一個相同的 eat 方法, 而且行為是完全一樣的.
2、這三個類都具備一個相同的 name 屬性, 而且意義是完全一樣的,
從邏輯上講, Cat 和 Bird 都是一種 Animal (is - a 語意).
此時我們就可以讓 Cat 和 Bird 分別繼承 Animal 類, 來達到代碼重用的效果.
此時, Animal 這樣被繼承的類, 我們稱為 父類 , 基類 或 超類, 對于像 Cat 和 Bird 這樣的類, 我們稱為 子類,或者派生類
和現實中的兒子繼承父親的財產類似, 子類也會繼承父類的欄位和方法, 以達到代碼重用的效果.
語法規則
class 子類 extends 父類 {
}
使用 extends 指定父類.
1、Java 中一個子類只能繼承一個父類 (而C++/Python等語言支持多繼承).
2、子類會繼承父類的所有 public 的欄位和方法.
3、對于父類的 private 的欄位和方法, 子類中是無法訪問的.
4、子類的實體中, 也包含著父類的實體. 可以使用 super 關鍵字得到父類實體的參考.
對于上面的代碼, 可以使用繼承進行改進. 此時我們讓 Cat 和 Bird 繼承自 Animal 類, 那么 Cat 在定義的時候就不必再寫 name 欄位和 eat 方法.
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 呼叫父類的構造方法.
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();
}
}

extends 英文原意指 “擴展”. 而我們所寫的類的繼承, 也可以理解成基于父類進行代碼上的 “擴展”.
例如我們寫的 Bird 類, 就是在 Animal 的基礎上擴展出了 fly 方法.
需要注意的是:在構造之類時需要先幫助父類構造
如果我們把 name 改成 private, 那么此時子類就不能訪問了.
class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println(this.name + "正在飛 ︿( ̄︶ ̄)︿");
}
}
Error:(19, 32) java: name 在 Animal 中是 private 訪問控制
protected 關鍵字
剛才我們發現, 如果把欄位設為 private, 子類不能訪問. 但是設成 public, 又違背了我們 “封裝” 的初衷.
兩全其美的辦法就是 protected 關鍵字.
1、對于類的呼叫者來說, protected 修飾的欄位和方法是不能訪問的
2、對于類的子類 和 同一個包的其他類 來說, protected 修飾的欄位和方法是可以訪問的
// Animal.java
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Bird.java
public class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
// 對于父類的 protected 欄位, 子類可以正確訪問
System.out.println(this.name + "正在飛 ︿( ̄︶ ̄)︿");
}
}
// Test.java 和 Animal.java 不在同一個 包 之中了.
public class Test {
public static void main(String[] args) {
Animal animal = new Animal("小動物");
System.out.println(animal.name); // 此時編譯出錯, 無法訪問 name
}
}
小結: Java 中對于欄位和方法共有四種訪問權限
1、private: 類內部能訪問, 類外部不能訪問
2、默認(也叫包訪問權限): 類內部能訪問, 同一個包中的類可以訪問, 其他類不能訪問.
3、protected: 類內部能訪問, 子類和同一個包中的類可以訪問, 其他類不能訪問.
4、public : 類內部和類的呼叫者都能訪問
final 關鍵字
曾經我們學習過 final 關鍵字, 修飾一個變數或者欄位的時候, 表示 常量 (不能修改).
final int a = 10;
a = 20; // 編譯出錯
final 關鍵字也能修飾類, 此時表示被修飾的類就不能被繼承.
final public class Animal {
...
}
public class Bird extends Animal {
...
}
Error:(3, 27) java: 無法從最終com.bit.Animal進行繼承
final 關鍵字的功能是限制 類被繼承
“限制” 這件事情意味著 “不靈活”.
在編程中, 靈活往往不見得是一件好事,靈活可能意味著更容易出錯,
是用 final 修飾的類被繼承的時候, 就會編譯報錯, 此時就可以提示我們這樣的繼承是有悖這個類設計的初衷的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/356975.html
標籤:java
上一篇:Java面向物件編程詳解
