## 1、繼承
* 繼承是一種類與類之間的關系
* 使用已存在的類的定義作為基礎建立新類
* 作為基礎的類一般稱為父類(基類),創建的新類稱為子類(派生類)
* 新類的定義可以增加新的數據或新的功能,也可以用父類的功能,但不能選擇性地繼承父類
* 滿足`A is a B`的關系就可以形成繼承關系
## 1.1 代碼實現
在 Java 中使用`extends`關鍵字來實現類的繼承,同時需要注意的是在 Java 中只能繼承一個父類。
* 編寫父類
```
public class Animal {
// 公共的屬性和方法
}
```
* 編寫子類,繼承父類
```
public class Dog extends Animal {
// 子類特有的屬性和方法
}
public class Cat extends Animal {
// ...
}
```
### 1.2 方法的重寫
方法重寫出現在有繼承關系的子類中,以下幾個要素都要與父類中允許繼承的方法相同
* 方法名
* 方法參數(類型、順序、個數)
> 方法的訪問修飾符是可以允許有變化的,重寫方法的訪問修飾符必須比父類方法的訪問修飾符范圍要大。
> 方法的返回值類型是可以允許有變化的,重寫方法的返回值類型必須與父類方法的返回值類型相同或者是其派生類
【閱讀】以下程序的輸出結果是()
```
public class Father {
public void print() {
System.out.println("Father-->print");
}
}
public class Son extends Father {
public void print() {
System.out.println("Son-->print");
}
public static void main(String[] args) {
Father f = new Father();
f.print();
}
}
```
【選擇】以下關于方法重載和方法重寫描述正確的是()(選擇一項)
```
A 方法重載和方法重寫實現的功能相同
B 方法重載出現在父子關系中,方法重寫是在同一類中
C 方法重載的返回類型必須一致,參數必須不同
D 方法重寫需要出現在滿足繼承關系的子類中
```
【選擇】那個選項中的方法插入到(1)處可以正確實現方法重寫()(選擇一項)
```
public class Animal {
public void eat(String food) {}
public static void bark() {}
public final void display() {}
}
public class Cat extends Animal {
// (1)
}
```
```
A public static void bark() {}
B public final void display() {}
C public void eat(String food) {}
D public boolean eat(String food) {}
```
【編程】接收用戶輸入的信息,選擇需要完成的工作任務。其中,可供選擇的有:測試工作和研發工作。程序運行參考效果圖如下:
```
父類信息測試:開心工作
測試工作類信息測試:測試工作的日報是:今天編寫了10個測試用例,發現了5個bug
研發工作類信息測試:研發工作的日報是:今天編寫了1000行代碼,目前仍然有10個bug沒有解決
```
```
public class Test {
public static void main(String[] args) {
System.out.print("父類信息測試:");
System.out.print("測試工作類信息測試:");
System.out.print("研發工作類信息測試:");
}
}
public class Work {
private String name; // 屬性:工作名
// 無參構造方法
// 帶參構造方法,完成工作類型的賦值
// 公有的get***/set***方法完成屬性封裝
// 方法:工作描述,描述內容為:開心工作
public String work() {
}
}
public class TestWork extends Work {
// 屬性:編寫的測試用例個數、發現的Bug數量
// 編寫構造方法,并調用父類相關賦值方法,完成屬性賦值
// 公有的get***/set***方法完成屬性封裝
/**
* 重寫運行方法,描述內容為:**的日報是:今天編寫了**個測試用例,發現了**bug。
* 其中**的數據由屬性提供
*/
public String work() {
}
}
public class DevelopmentWork extends Work {
// 屬性:有效編碼行數、目前沒有解決的Bug個數
// 編寫構造方法,并調用父類相關賦值方法,完成屬性賦值
// 公有的get***/set***方法完成屬性封裝
/**
* 重寫運行方法,描述內容為:**的日報是:今天編寫了**行代碼,目前仍然有**個bug沒有解決。
* 其中**的數據由屬性提供
*/
public String work() {}
}
```
### 1.3 訪問修飾符的分類及使用
| 訪問修飾符 | 本類 | 同包 | 子類 | 其他 |
| :-: | :-: | :-: | :-: | :-: |
| private | yes | no | no | no |
| 默認 | yes | yes | no | no |
| protected | yes | yes | yes | no |
| public | yes | yes | yes | yes |
【選擇】在下面程序的注釋(1)處補充下列()方法,會導致在編譯過程中發生錯誤(選擇一項)
```
public class Father {
public float getNum() {
return 3.0f;
}
}
public class Son extends Father {
// (1)
}
```
```
A public float getNum() { return 4.0f; }
B private float getNum() { return 4.0f; }
C public void getNum(double d) {}
D public double getNum(float d) { return 4.0f;}
```
【選擇】代碼位置(1)處填寫()選項,可以使代碼編譯通過。(選擇三項)
```
public class Alpha {
public void bar(int x) {}
public void bar(int... x) {}
}
public class Beta extends Alpha {
// (1)
}
```
```
A private void bar(int x) {}
B public void bar(int x) {}
C public int bar(String x) { return 1; }
D public Alpha bar(int x) { return new Alpha(); }
E public void bar(int x, int y) {}
F public int bar(int x) { reutrn x; }
```
### 1.4 `super`關鍵字
我們使用 super 關鍵字在子類中來表示對父類對象的引用。
* 訪問父類成員方法 super.方法名();
* 訪問父類屬性 super.屬性();
* 訪問父類構造方法 super();
> 子類構造方法默認會調用父類的無參構造方法
> 可以通過 super() 調用父類允許被訪問的其他構造方法
> super() 必須方法在子類構造方法有效代碼第一行
【閱讀】以下程序的輸出結果是()
```
package foo;
public class Father {
public Father() {
System.out.println("Father Create");
}
}
package test;
import foo.Father;
public class Child extends Father {
public Child() {
System.out.println("Child Create");
}
public static void main(String[] args) {
Father father = new Father();
Child child = new Child();
}
}
```
【閱讀】如下源代碼,編譯并運行Child.java后,結果為()
```
public class Parent1 {
public Parent1(String s) {
System.out.println(s);
}
}
public class Parent2 extends Parent1 {
public Parent2() {
System.out.println("parent2");
}
}
public class Child extends Parent2 {
public static void main(String[] args) {
Child child = new Child():
}
}
```
【選擇】分析如下所示的Java代碼,則選項中的說法正確的是()(選擇一項)
```
public class Parent {
public String name;
public Parent(String name) {
this.name = name;
}
}
public class Test extends Parent {
public Test(String name) { // (1)
name = "hello"; // (2)
super("kitty"); // (3)
}
}
```
```
A 第(1)行錯誤,Test 類的構造函數中參數名稱應與其父類構造函數中的參數名相同
B 第(2)行錯誤,應使用 super 關鍵字調用父類的 name 屬性,改為 super.name = "hello"
C 第(3)行錯誤,調用父類構造方法的語句必須放在子類構造方法的第一行
D 程序編譯通過,無錯誤
```
【選擇】關于 super 的說法正確的是()(選擇一項)
```
A 是指當前子類的對象
B 是指當前類的對象
C 是指當前父類的對象
D 可以用在 mian() 方法中
```
【閱讀】閱讀下面代碼片段,結果為()
```
public class Car {
String color;
String motor;
public Car(String color, String motor) {
this.color = color;
this.motor = motor;
}
}
public class Truck extends Car {
double weight;
public Truck() {}
public Truck(String color, String motor, double weight) {
super(color, motor);
this.weight = weight;
}
public void display() {
System.out.println("顏色:" + color);
System.out.println("發動機的型號:" + motor);
System.out.println("載重量:" + weight);
}
public static void main(String[] args) {
Truck truck = new Truck("紅色", "玉柴", 1.5);
truck.display();
}
}
```
【選擇】下列關于 super 和 this 的說法錯誤的是()(選擇一項)
```
A this 關鍵字通常指當前對象
B super 關鍵字則指父類對象
C 在一個類中 this 只可以調用當前類中共有屬性和方法
D 在一個類中 super 可以調用父類中允許被訪問的屬性和方法
```
【多選】某公司要開發“XX車行管理系統”,請使用面向對象的思想,設計自定義類描述自行車、電動車和三輪車。程序參考運行效果圖如下:
```
父類信息測試:這是一輛紅顏色的,天宇牌的非機動車,有4個輪子,有2個座椅
自行車類信息測試:這是一輛黃顏色的,捷安特牌的自行車
電動車類信息測試:這是一輛使用飛鴿牌電池的電動車
三輪車類信息測試:三輪車是一款有3個輪子的非機動車
```
```
public class Test {
public static void main(String[] args) {
System.out.print("父類信息測試:");
System.out.print("自行車類信息測試:");
System.out.print("電動車類信息測試:");
System.out.print("三輪車類信息測試:");
}
}
public class NonMotor {
// 私有屬性:品牌、顏色、輪子(默認2個)、座椅(默認 1個)
// 無參構造方法
// 雙參構造方法,完成對品牌和顏色的賦值
// 四參構造方法,分別對所有屬性賦值
// 公有的get***/set***方法完成屬性封裝
/**
* 方法:運行,描述內容為:這是一輛**顏色的,**牌的非機動車,有**個輪子,有**個座椅的非機動車。
* 其中**的數據由屬性提供
*/
public String work() {
}
}
public class Bicyle extends NonMotor {
// 在構造方法中調用父類多參構造,完成屬性賦值
// 重寫運行方法,描述內容為:這是一輛**顏色的,**牌的自行車。其中**的數據由屬性提供
}
public class ElectricVehicle extends NonMotor {
// 私有屬性:電池品牌
// 公有的get***/set***方法完成屬性封裝
// 重寫運行方法,描述內容為:這是一輛使用**牌電池的電動車。其中**的數據由屬性提供
}
public class Tricycle extends NonMotor {
// 在無參構造中實現對輪子屬性值進行修改
// 重寫運行方法,描述內容為:三輪車是一款有**個輪子的非機動車。其中**的數據由屬性提供
}
```
## 2、Object 類
* `Object`類是所有類的父類
* 一個類沒有使用`extends`關鍵字明確標識繼承關系,則默認繼承`Object`類(包括數組)
* Java 中的每一個類都可以使用`Object`類中定義的方法
### 2.1 `equals()`方法
* 繼承`Object`中的`equals`方法時,比較的是兩個引用是否指向同一個對象
* 子類可以通過重寫`equals`方法的形式,改變比較的內容
### 2.2 `toString()`方法
* 輸出對象名時,默認會直接調用類中`toString()`
* 繼承`Object`中的`toString`方法時,輸出對象的字符串表示形式:`類型信息@哈希碼`
* 子類可以通過重寫`toString`方法的形式,改變輸出的內容以及表現形式
【選擇】下列關于 Object 類的描述錯誤的是()(選擇一項)
```
A Object 類是所有類的父類
B 所有類都可以繼承 Object 中允許被繼承的方法
C 一個類沒有使用 extends 關鍵字明確標識繼承關系,則默認繼承 Object 類
D 要想繼承 Object 類,必須使用 extends 關鍵字標識繼承關系,否則不會實現繼承
```
【閱讀】該段代碼的運行結果為()
```
public class Father {
private String name;
private int age;
public Father (String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Father fa1 = new Father("小明", 13);
Father fa2 = new Father("小明", 13);
boolean flag = fa1.equals(fa2);
System.out.println(flag);
}
}
```
【編程】請使用面向對象的思想,設計自定義類 Person 繼承 Object 類,重寫 toString 方法實現對象信息輸出。運行效果如下圖所示:
```
姓名:李明,年齡:18,性別:男
姓名:陳紅,年齡:17,性別:女
```
```
public class Test {
public static void main(String[] args) {
// 實例化對象,傳入屬性值
// 打印輸出對象信息
}
}
public class Person {
// 私有屬性:name(姓名)、age(年齡)、sex(性別)
// 帶參構造方法(name、age、sex為參數)
// 通過封裝實現對屬性的get/set方法設定
// 重寫toString方法,表示形式為:姓名:+**+ 年齡:+**+ 性別:+**
}
```
## 3、final 關鍵字
* 修飾類:該類不允許被繼承
* 修飾方法:該方法不允許被重寫
* 修飾成員屬性:賦值必須在實例對象之前
賦值過程:1、定義直接初始化 2、構造代碼塊內 3、構造方法內
* 修飾局部變量:只要在使用之前進行賦值即可,一旦賦值不允許被修改
* 基本數據類型的變量:初始賦值之后不能改變
* 引用類型的變量:初始化之后不能再指向另一個對象
【選擇】下列關于`final`的說法正確的是()
```
A final 修飾的變量值不允許被修改
B final 修飾的方法不可被重寫
C final 可以修飾所有方法
D final 不可以修飾構造方法
```
* `MAX_LENGTH`是`int`型`public`成員變量,數值保持為常量100,應該如何定義()
## 4、注解
* `JDK 1.5`版本引入的一個特性
* 可以聲明在包、類、屬性、方法、局部變量、方法參數等的前面,用來對這些元素進行說明、注釋
按照運行機制分:
* 源碼注解:注解只在源碼中存在,編譯成`.class`文件就不存在了。
* 編譯時注解:注解在源碼和`.class`文件都存在。
* 運行時注解:在運行階段還起作用,甚至會影響運行邏輯的注解。
【編程】請使用面向對象的思想,實現楊梅和仙人蕉的信息描述。程序參考運行效果圖如下:
```
水果可供人們食用!
fru1和fru2的引用比較:true
-----------------------
楊梅:紫紅色、圓形、果味酸甜適中。
楊梅酸甜適中,非常好吃!
楊梅的信息:果實為圓形、紫紅色、酸甜適中、非常好吃!
-----------------------
仙人蕉果形短而稍圓、果肉香甜、可供生食。
仙人蕉顏色為黃色
```
```
public class Test {
public static void main(String[] args) {
// 實例化2個父類對象,傳入兩組相同的參數值
// 調用父類eat方法
// 測試重寫equals方法,判斷兩個對象是否相等
System.out.println("-----------------------");
// 實例化子類對象,并傳入相關參數值
// 調用子類face方法和eat方法
// 測試重寫toString方法,輸出子類對象的信息
System.out.println("-----------------------");
// 實例化Banana類對象,并傳入相關參數值
// 調用子類的advantage和它的重載方法
}
}
public class Fruits {
// 私有屬性:水果的形狀(shape)和口感(taste)
// 無參構造器
// 帶參構造函數(參數為shape和taste)
// 通過封裝實現對私有屬性的get/set訪問
// 創建無參無返回值得方法eat(描述內容為:水果可供人們食用!)
// 重寫equals方法,比較兩個對象是否相等(比較shape,taste)
}
public class Waxberry {
// 私有屬性:顏色(color)
//創建構造方法,完成調用父類的構造方法,完成屬性賦值
//創建不允許重寫的face方法,描述為:楊梅:**、**,果味酸甜適中
//重寫父類eat方法,描述為:楊梅酸甜適中,非常好吃!
//重寫toString方法,輸出的表現形式不同(輸出shape,color,taste)
}
public class Banana {
// 私有屬性:品種(variety)
//創建帶參構造方法為所有屬性賦值
//創建無參無返回值的advantage方法,描述為:**果形**,果肉香甜,可供生食。
//創建重載advantage方法(帶參數color),描述為:**顏色為**
}
```
【編程】請使用面向對象的思想,實現出租車和家用轎車的信息描述。程序運行參考效果如下:
```
我是機動車!
car1和car2的引用比較:true
========================
張小泉的出租車是屬于長生公司的
出租車是提高市民生活質量的重要條件之一
taxi的信息是:張小泉擁有一輛藍色的出租車
========================
孫二娘擁有的紫色顏色的私家車,有7座位
家用汽車大多有5個座位
```
```
public class Test {
public static void main(String[] args){
//實例化父類對象,并傳入兩組相同的屬性值
//調用父類use方法
//通過重寫equals方法,比較兩個對象是否相等
System.out.println("========================");
//實例化子類Taxi對象,并傳入屬性值
//調用ride和use方法
//輸出重寫toString后的taxi信息
System.out.println("========================");
//實例化子類HomeCar對象,并傳入屬性值
//調用display方法及它的重載方法
}
}
public class Car {
// 屬性:車的顏色color、車主姓名userName
// 無參構造函數
// 帶參構造函數(參數為color和useName)
// 通過封裝實現對私有屬性的get/set操作
// 創建無參無返回值得方法use(描述內容為:我是機動車!)
// 重寫equals方法,比較兩個對象是否相等(比較color,userName)
}
public class Taxi extends Car{
// 私有屬性:所屬公司(company)
// 無參構造方法
// 調用父類的構造方法,完成屬性賦值
// 通過封裝實現對私有屬性的get/set操作
// 創建不允許重寫的ride方法,描述為:**出租車是所屬于***公司的。
// 重寫父類use方法,描述為:出租車是提高市民生活質量的重要條件之一
// 重寫toString方法,輸出的表現形式不同(輸出color,userName)
}
public final class HomeCar extends Car{
// 私有屬性:載客數(num)
// 帶參構造方法為所有屬性賦值
// 通過封裝實現對私有屬性的get/set操作
// 創建無參無返回值的display方法,表現為:**擁有的**顏色的私家車,有**座位
// 重載display方法(帶參數num),描述為:家用汽車大多有**個座位
}
```
- 階段一 Java 零基礎入門
- 步驟1:基礎語法
- 第01課 初識
- 第02課 常量與變量
- 第03課 運算符
- 第04課 選擇結構
- 第05課 循環結構
- 第06課 一維數組
- 第08課 方法
- 第09課 數組移位與統計
- 第10課 基礎語法測試
- 第09課 基礎語法測試(含答案)
- 步驟2:面向對象
- 第01課 類和對象
- 第02課 封裝
- 第03課 學生信息管理
- 第04課 繼承
- 第05課 單例模式
- 第06課 多態
- 第07課 抽象類
- 第08課 接口
- 第09課 內部類
- 第10課 面向對象測試
- 第10課 面向對象測試(含答案)
- 步驟3:常用工具類
- 第01課 異常
- 第02課 包裝類
- 第03課 字符串
- 第04課 集合
- 第05課 集合排序
- 第06課 泛型
- 第07課 多線程
- 第08課 輸入輸出流
- 第09課 案例:播放器
- 第10課 常用工具測試(一)
- 第10課 常用工具測試(一)(答案)
- 第10課 常用工具測試(二)
- 第10課 常用工具測試(二)(答案)
- 階段二 從網頁搭建入門 JavaWeb
- 步驟1:HTML 與 CSS
- 第01課 HTML 入門
- 第01課 HTML 入門(作業)
- 第02課 CSS 入門
- 第02課 CSS 入門(作業)
- 第03課 CSS 布局
- 第03課 CSS 布局(作業)
- 步驟2:JavaScript 與前端案例
- 第01課 JavaScript 入門
- 第01課 JavaScript 入門(作業)
- 第02課 仿計算器
- 第03課 前端油畫商城案例
- 第04課 輪播圖
- 第05課 網頁搭建測試
- 第05課 網頁搭建測試(含答案)
- 步驟3:JavaScript 教程
- 入門
- 概述
- 基本語法
- 數據類型
- 概述
- 數值
- 字符串
- undefined, null 和布爾值
- 對象
- 函數
- 數組
- 運算符
- 算術運算符
- 比較運算符
- 布爾運算符
- 位運算符
- 運算順序
- 語法專題
- 數據類型的轉換
- 錯誤處理機制
- 標準庫
- String
- Date
- Math
- DOM
- 概述
- Document 節點
- 事件
- EventTarget 接口
- 事件模型
- 常見事件
- 階段三 數據庫開發與實戰
- 步驟1:初始數據庫操作
- 第01課 數據類型
- 第02課 表的管理
- 第03課 數據管理
- 第04課 常用函數
- 第05課 JDBC 入門
- 第06課 Java 反射
- 第07課 油畫商城
- 第08課 數據庫基礎測試
- 步驟2:MyBatis 從入門到進階
- 第01課 IntelliJ IDEA 開發工具入門
- 第02課 Maven 入門
- 第03課 工廠模式
- 第04課 MyBatis 入門
- 第05課 MyBatis 進階
- 第06課 商品信息管理
- 第07課 MyBatis 基礎測試
- 步驟3:Redis 數據庫與 Linux 下項目部署
- 第01課 Linux 基礎
- 第02課 Linux 下 JDK 環境搭建及項目部署
- 第03課 Redis 入門
- 階段四 SSM 到 Spring Boot 入門與綜合實戰
- 步驟1:Spring 從入門到進階
- 第01課 Spring 入門
- 第02課 Spring Bean 管理
- 第03課 Spring AOP
- 第04課 基于 AspectJ 的 AOP 開發
- 第05課 JDBC Template
- 第06課 Spring 事務管理
- 第07課 人員管理系統開發
- 第08課 Spring 從入門到進階測試
- 步驟2:Spring MVC 入門與 SSM 整合開發
- 第01課 Spring MVC 入門與數據綁定
- 第02課 Restful 風格的應用
- 第03課 SpringMVC 攔截器
- 第04課 辦公系統核心模塊
- 步驟3:Spring Boot 實戰
- 第01課 Spring Boot 入門
- 第02課 校園商鋪項目準備
- 第03課 校園商鋪店鋪管理
- 第04課 校園商鋪商品管理及前臺展示
- 第05課 校園商鋪框架大換血
- 步驟4:Java 面試
- 第01課 面試準備
- 第02課 基礎面試技巧
- 第03課 Web基礎與數據處理
- 第04課 主流框架