今日收獲:
1.this代表本類 super代表父類
2.子類建立對象自動通路父類中的無參構造
3.子類可通過super通路父類構造方法
super() //調用父類無參構造和成員方法
super(name,age) //給他初始化
4.static 共享的 修飾成員變量和方法
(1)被類的所有對象共享
(2)類名調用(不用建立對象)
(3)優先于對象存在
(4)随着類的加載而加載(隻加載一次)靜态隻能通路靜态
多态:
(1)有繼承關系
(2)有子類重寫父類方法
(3)父類引用指向子類對象
## 1. 繼承
### 1.1 繼承的實作(掌握)
* 繼承的概念
* 繼承是面向對象三大特征之一,可以使得子類具有父類的屬性和方法,還可以在子類中重新定義,以及追加屬性和方法
* 實作繼承的格式
* 繼承通過extends實作
* 格式:class 子類 extends 父類 { }
* 舉例:class Dog extends Animal { }
* 繼承帶來的好處
* 繼承可以讓類與類之間産生關系,子父類關系,産生子父類後,子類則可以使用父類中非私有的成員。
* 示例代碼
```java
public class Fu {
public void show() {
System.out.println("show方法被調用");
}
}
public class Zi extends Fu {
public void method() {
System.out.println("method方法被調用");
}
}
public class Demo {
public static void main(String[] args) {
//建立對象,調用方法
Fu f = new Fu();
f.show();
Zi z = new Zi();
z.method();
z.show();
}
}
```
### 1.2 繼承的好處和弊端(了解)
* 繼承好處
* 提高了代碼的複用性(多個類相同的成員可以放到同一個類中)
* 提高了代碼的維護性(如果方法的代碼需要修改,修改一處即可)
* 繼承弊端
* 繼承讓類與類之間産生了關系,類的耦合性增強了,當父類發生變化時子類實作也不得不跟着變化,削弱了子類的獨立性
* 繼承的應用場景:
* 使用繼承,需要考慮類與類之間是否存在is..a的關系,不能盲目使用繼承
* is..a的關系:誰是誰的一種,例如:老師和學生是人的一種,那人就是父類,學生和老師就是子類
## 2. 繼承中的成員通路特點
### 2.1 繼承中變量的通路特點(掌握)
在子類方法中通路一個變量,采用的是就近原則。
1. 子類局部範圍找
2. 子類成員範圍找
3. 父類成員範圍找
4. 如果都沒有就報錯(不考慮父親的父親…)
* 示例代碼
```java
class Fu {
int num = 10;
}
class Zi {
int num = 20;
public void show(){
int num = 30;
System.out.println(num);
}
}
public class Demo1 {
public static void main(String[] args) {
Zi z = new Zi();
z.show(); // 輸出show方法中的局部變量30
}
}
```
### 2.2 super(掌握)
* this&super關鍵字:
* this:代表本類對象的引用
* super:代表父類存儲空間的辨別(可以了解為父類對象引用)
* this和super的使用分别
* 成員變量:
* this.成員變量 - 通路本類成員變量
* super.成員變量 - 通路父類成員變量
* 成員方法:
* this.成員方法 - 通路本類成員方法
* super.成員方法 - 通路父類成員方法
* 構造方法:
* this(…) - 通路本類構造方法
* super(…) - 通路父類構造方法
### 2.3 繼承中構造方法的通路特點(了解)
**注意:子類中所有的構造方法預設都會通路父類中無參的構造方法**
子類會繼承父類中的資料,可能還會使用父類的資料。是以,子類初始化之前,一定要先完成父類資料的初始化,原因在于,每一個子類構造方法的第一條語句預設都是:super()
**問題:如果父類中沒有無參構造方法,隻有帶參構造方法,該怎麼辦呢?**
1. 通過使用super關鍵字去顯示的調用父類的帶參構造方法
2. 在父類中自己提供一個無參構造方法
**推薦方案:**
自己給出無參構造方法
### 2.4 繼承中成員方法的通路特點(掌握)
通過子類對象通路一個方法
1. 子類成員範圍找
2. 父類成員範圍找
3. 如果都沒有就報錯(不考慮父親的父親…)
### 2.5 super記憶體圖(了解)
* 對象在堆記憶體中,會單獨存在一塊super區域,用來存放父類的資料
![圖檔1](F:\TeachRes\2019\JavaSe\day01\筆記\筆記資源包\圖檔1.png)
### 2.6 方法重寫(掌握)
* 1、方法重寫概念
* 子類出現了和父類中一模一樣的方法聲明(方法名一樣,參數清單也必須一樣)
* 2、方法重寫的應用場景
* 當子類需要父類的功能,而功能主體子類有自己特有内容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的内容
* 3、Override注解
* 用來檢測目前的方法,是否是重寫的方法,起到【校驗】的作用
### 2.7 方法重寫的注意事項(掌握)
* 方法重寫的注意事項
1. 私有方法不能被重寫(父類私有成員子類是不能繼承的)
2. 子類方法通路權限不能更低(public > 預設 > 私有)
* 示例代碼
```java
public class Fu {
private void show() {
System.out.println("Fu中show()方法被調用");
}
void method() {
System.out.println("Fu中method()方法被調用");
}
}
public class Zi extends Fu {
@Override
private void show() {
System.out.println("Zi中show()方法被調用");
}
@Override
private void method() {
System.out.println("Zi中method()方法被調用");
}
@Override
public void method() {
System.out.println("Zi中method()方法被調用");
}
}
```
### 2.8. Java中繼承的注意事項(掌握)
* Java中繼承的注意事項
1. Java中類隻支援單繼承,不支援多繼承
* 錯誤範例:class A extends B, C { }
2. Java中類支援多層繼承
* 多層繼承示例代碼:
```java
public class Granddad {
public void drink() {
System.out.println("爺爺愛喝酒");
}
}
public class Father extends Granddad {
public void smoke() {
System.out.println("爸爸愛抽煙");
}
}
public class Mother {
public void dance() {
System.out.println("媽媽愛跳舞");
}
}
public class Son extends Father {
// 此時,Son類中就同時擁有drink方法以及smoke方法
}
```
## 3. 繼承練習
### 3.1 老師和學生(應用)
* 需求:定義老師類和學生類,然後寫代碼測試;最後找到老師類和學生類當中的共性内容,抽取出一個父類,用繼承的方式改寫代碼,并進行測試
* 步驟:
①定義老師類(姓名,年齡,教書())
②定義學生類(姓名,年齡,學習())
③定義測試類,寫代碼測試
④共性抽取父類,定義人類(姓名,年齡)
⑤定義老師類,繼承人類,并給出自己特有方法:教書()
⑥定義學生類,繼承人類,并給出自己特有方法:學習()
⑦定義測試類,寫代碼測試
* 示例代碼:
```java
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Teacher extends Person {
public Teacher() {}
public Teacher(String name,int age) {
super(name,age);
}
public void teach() {
System.out.println("用愛成就每一位學員");
}
}
class Student extends Person{
public Student() {}
public Student(String name, int age) {
super(name,age);
}
public void study(){
System.out.println("學生學習");
}
}
class PersonDemo {
public static void main(String[] args){
//建立老師類對象并進行測試
Teacher t1 = new Teacher();
t1.setName("林青霞");
t1.setAge(30);
System.out.println(t1.getName() + "," + t1.getAge());
t1.teach();
Teacher t2 = new Teacher("風清揚", 33);
System.out.println(t2.getName() + "," + t2.getAge());
t2.teach();
// 建立學生類對象測試
Student s = new Student("張三",23);
System.out.println(s.getName() + "," + s.getAge());
s.study();
}
}
```
### 3.2 貓和狗( 應用)
* 需求:請采用繼承的思想實作貓和狗的案例,并在測試類中進行測試
* 分析:
①貓:
成員變量:姓名,年齡
構造方法:無參,帶參
成員方法:get/set方法,抓老鼠()
②狗:
成員變量:姓名,年齡
構造方法:無參,帶參
成員方法:get/set方法,看門()
③共性:
成員變量:姓名,年齡;構造方法:無參,帶參;成員方法:get/set方法
* 步驟:
1、定義動物類(Animal)
【成員變量:姓名,年齡】【 構造方法:無參,帶參】【成員方法:get/set方法】
2、定義貓類(Cat),繼承動物類
【構造方法:無參,帶參】【成員方法:抓老鼠() 】
3、定義狗類(Dog),繼承動物類
【構造方法:無參,帶參】【成員方法:看門() 】
4、定義測試類(AnimalDemo),寫代碼測試
* 示例代碼:
```java
class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
public void catchMouse() {
System.out.println("貓抓老鼠");
}
}
class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
public void lookDoor() {
System.out.println("狗看門");
}
}
public class AnimalDemo {
public static void main(String[] args) {
//建立貓類對象并進行測試
Cat c1 = new Cat();
c1.setName("加菲貓");
c1.setAge(5);
System.out.println(c1.getName() + "," + c1.getAge());
c1.catchMouse();
Cat c2 = new Cat("加菲貓", 5);
System.out.println(c2.getName() + "," + c2.getAge());
c2.catchMouse();
}
}
```
## 4. 修飾符
### 4.1 package(了解)
* 1、包的概念
* 包就是檔案夾,用來管理類檔案的
* 2、包的定義格式
* package 包名; (多級包用.分開)
* 例如:package com.heima.demo;
* 3、帶包編譯&帶包運作
* 帶包編譯:javac –d . 類名.java
* 例如:javac -d . com.heima.demo.HelloWorld.java
* 帶包運作:java 包名+類名
* 例如:java com.heima.demo.HelloWorld
### 4.2 import(了解)
* 導包的意義
使用不同包下的類時,使用的時候要寫類的全路徑,寫起來太麻煩了
為了簡化帶包的操作,Java就提供了導包的功能
* 導包的格式
格式:import 包名;
範例:import java.util.Scanner;
* 示例代碼(沒有使用導包,建立的Scanner對象)
```java
package com.heima;
public class Demo {
public static void main(String[] args) {
// 1. 沒有導包,建立Scnaner對象
java.util.Scanner sc = new java.util.Scanner(System.in);
}
}
```
* 示例代碼(使用導包後,建立的Scanner對象)
```java
package com.heima;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
// 1. 沒有導包,建立Scnaner對象
Scanner sc = new Scanner(System.in);
}
}
```
### 4.3 權限修飾符(了解)
![圖檔2](F:\TeachRes\2019\JavaSe\day01\筆記\筆記資源包\圖檔2.png)
### 4.4 final(應用)
* fianl關鍵字的作用
* final代表最終的意思,可以修飾成員方法,成員變量,類
* final修飾類、方法、變量的效果
* fianl修飾類:該類不能被繼承(不能有子類,但是可以有父類)
* final修飾方法:該方法不能被重寫
* final修飾變量:表明該變量是一個常量,不能再次指派
### 4.5 final修飾局部變量(了解)
* fianl修飾基本資料類型變量
* final 修飾指的是基本類型的資料值不能發生改變
* final修飾引用資料類型變量
* final 修飾指的是引用類型的位址值不能發生改變,但是位址裡面的内容是可以發生改變的
* 舉例:
```java
public static void main(String[] args){
final Student s = new Student(23);
s = new Student(24); // 錯誤
s.setAge(24); // 正确
}
```
### 4.6 static(應用)
* static的概念
* static關鍵字是靜态的意思,可以修飾【成員方法】,【成員變量】
* static修飾的特點
1. 被類的所有對象共享,這也是我們判斷是否使用靜态關鍵字的條件
2. 可以通過類名調用當然,也可以通過對象名調用**【推薦使用類名調用】**
* 示例代碼:
```java
class Student {
public String name; //姓名
public int age; //年齡
public static String university; //學校 共享資料!是以設計為靜态!
public void show() {
System.out.println(name + "," + age + "," + university);
}
}
public class StaticDemo {
public static void main(String[] args) {
// 為對象的共享資料指派
Student.university = "傳智大學";
Student s1 = new Student();
s1.name = "林青霞";
s1.age = 30;
s1.show();
Student s2 = new Student();
s2.name = "風清揚";
s2.age = 33;
s2.show();
}
}
```
### 4.7 static通路特點(掌握)
* static的通路特點
* 非靜态的成員方法
* 能通路靜态的成員變量
* 能通路非靜态的成員變量
* 能通路靜态的成員方法
* 能通路非靜态的成員方法
* 靜态的成員方法
* 能通路靜态的成員變量
* 能通路靜态的成員方法
* 總結成一句話就是:
* **靜态成員方法隻能通路靜态成員**
## 5.多态
### 5.1多态的概述(記憶)
- 什麼是多态
同一個對象,在不同時刻表現出來的不同形态
- 多态的前提
- 要有繼承或實作關系
- 要有方法的重寫
- 要有父類引用指向子類對象
### 5.2多态中的成員通路特點(記憶)
- 成員通路特點
- 成員變量
編譯看父類,運作看父類
- 成員方法
編譯看父類,運作看子類
- 代碼示範
- 動物類
```java
public class Animal {
public int age = 40;
public void eat() {
System.out.println("動物吃東西");
}
}
```
- 貓類
```java
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
@Override
public void eat() {
System.out.println("貓吃魚");
}
public void playGame() {
System.out.println("貓捉迷藏");
}
}
```
- 測試類
```java
public class AnimalDemo {
public static void main(String[] args) {
//有父類引用指向子類對象
Animal a = new Cat();
System.out.println(a.age);
// System.out.println(a.weight);
a.eat();
// a.playGame();
}
}
```
### 5.3多态的好處和弊端(記憶)
- 好處
提高程式的擴充性。定義方法時候,使用父類型作為參數,在使用的時候,使用具體的子類型參與操作
- 弊端
不能使用子類的特有成員
### 5.4多态中的轉型(應用)
- 向上轉型
父類引用指向子類對象就是向上轉型
- 向下轉型
格式:子類型 對象名 = (子類型)父類引用;
- 代碼示範
- 動物類
```java
public class Animal {
public void eat() {
System.out.println("動物吃東西");
}
}
```
- 貓類
```java
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("貓吃魚");
}
public void playGame() {
System.out.println("貓捉迷藏");
}
}
```
- 測試類
```java
public class AnimalDemo {
public static void main(String[] args) {
//多态
//向上轉型
Animal a = new Cat();
a.eat();
// a.playGame();
//向下轉型
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}
```
### 5.5多态的案例(應用)
- 案例需求
請采用多态的思想實作貓和狗的案例,并在測試類中進行測試
- 代碼實作
- 動物類
```java
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("動物吃東西");
}
}
```
- 貓類
```java
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("貓吃魚");
}
}
```
- 狗類
```java
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨頭");
}
}
```
- 測試類
```java
public class AnimalDemo {
public static void main(String[] args) {
//建立貓類對象進行測試
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
a = new Cat("加菲", 5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
}
}
```
## 6.抽象類
### 6.1抽象類的概述(了解)
當我們在做子類共性功能抽取時,有些方法在父類中并沒有具體的展現,這個時候就需要抽象類了!
在Java中,一個沒有方法體的方法應該定義為抽象方法,而類中如果有抽象方法,該類必須定義為抽象類!
### 6.2抽象類的特點(記憶)
- 抽象類和抽象方法必須使用 abstract 關鍵字修飾
```java
//抽象類的定義
public abstract class 類名 {}
//抽象方法的定義
public abstract void eat();
```
- 抽象類中不一定有抽象方法,有抽象方法的類一定是抽象類
- 抽象類不能執行個體化
抽象類如何執行個體化呢?參照多态的方式,通過子類對象執行個體化,這叫抽象類多态
- 抽象類的子類
要麼重寫抽象類中的所有抽象方法
要麼是抽象類
### 6.3抽象類的成員特點(記憶)
- 成員的特點
- 成員變量
- 既可以是變量
- 也可以是常量
- 構造方法
- 空參構造
- 有參構造
- 成員方法
- 抽象方法
- 普通方法
- 代碼示範
- 動物類
```java
public abstract class Animal {
private int age = 20;
private final String city = "北京";
public Animal() {}
public Animal(int age) {
this.age = age;
}
public void show() {
age = 40;
System.out.println(age);
// city = "上海";
System.out.println(city);
}
public abstract void eat();
}
```
- 貓類
```java
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("貓吃魚");
}
}
```
- 測試類
```java
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.eat();
a.show();
}
}
```