多態
概念
父類引用指向子類對象
父類類型的一個變量中存儲了一個子類的對象
多態的理解
一個事物是什么取決於你認為它是什么(引用類型)
你認為的 ---> 引用類型
一個事物是什么 ----> 對象
多態的概念
- 屬性沒有多態(不研究)
- 成員方法具有多態
-(1)編譯時多態————在編譯時只能調用引用類型所對應類中聲明的方法
-(2)運行時多態————在多態發生時,運行時調用的是子類重寫父類后的方法實現 - 口訣
編譯看左邊 運行看右邊
左邊 = 右邊
舉例:
Animal animal = new Cat();
多態中類型之間的轉換
-
對象一旦創建其類型不可以變
-
向上轉型
將子類類型的對象引用,賦值給父類類型引用。
意義: 可以忽略 子類之間的差異,提升為父類類型進行統一的處理
- 向下轉型
將父類類型的引用 賦值給子類的引用
意義: 恢復類子類原來的特征 通過向下轉型 可以調用子類中特有的方法
類型轉換異常
//Exception in thread "main" java.lang.ClassCastException: Demo1.Cat cannot be cast to Dmeo1.Dog
// at Demo1.main(Demo1.java:14)
當使用強制的方法進行轉換的時候,可能會發生類型轉換異常.
instanceof 語句(實例屬於 )
-
語法
引用名 instanceof 類型
-
作用
判斷一個引用中引用的對象是什么類型的數據
-
案例
package com.ujiuye.day10;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
// Animal animal = new Cat();
//
// boolean f = animal instanceof Dog;// animal 變量中引用的對象的類型是否屬於 dog 類型
// System.out.println(f);
Animal animal = new Dog();
if (animal instanceof Dog){
//進行向下轉型
Dog dog = (Dog) animal;
dog.eat();
dog.sleep();
dog.shout();
}else{
Cat cat = (Cat) animal;
cat.eat();
cat.sleep();
cat.catchMouse();
}
}
}
//動物類
class Animal{
String name;
int age;
public void eat(){
System.out.println("動物吃");
}
public void sleep(){
System.out.println("動物睡覺");
}
}
//狗類
class Dog extends Animal{
//重寫 父類中的方法
@Override
public void eat() {
System.out.println("狗汪汪汪的吃肉");
}
@Override
public void sleep() {
System.out.println("狗趴着睡覺");
}
//特有的方法
public void shout(){
System.out.println("狗汪汪汪的叫");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("貓喵喵的吃魚");
}
@Override
public void sleep() {
System.out.println("貓 呼呼的睡覺");
}
//特有的功能
public void catchMouse(){
System.out.println("貓抓老鼠");
}
}
多態的應用
- 多態用在數組中
package com.ujiuye.day10;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
//創建一個動物園
// zoo 里邊 的每個元素的引用是什么類型 Animal 但是存放的是 子類對象 父類引用指向子類對象
Animal[] zoo = {
new Dog(),
new Cat(),
new Cat(),
new Wolf(),
new Wolf(),
new Wolf(),
new Wolf(),
new Monkey(),
new Monkey(),
};
//假設 現在動物園開飯了
//通過循環
for (int i = 0; i < zoo.length; i++) {
zoo[i].eat();
}
}
}
//動物類
class Animal{
public void eat(){
System.out.println("動物吃");
}
public void sleep(){
System.out.println("動物睡覺");
}
}
//狗類
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗汪汪汪的吃肉");
}
//特有的方法
public void shout(){
System.out.println("狗汪汪汪的叫");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("貓喵喵的吃魚");
}
//特有的功能
public void catchMouse(){
System.out.println("貓抓老鼠");
}
}
//猴子
class Monkey extends Animal{
@Override
public void eat() {
System.out.println("猴子吃桃");
}
}
//狼
class Wolf extends Animal{
@Override
public void eat() {
System.out.println("狼吃羊");
}
}
-
多態用在方法的參數上
-
多態用在方法的返回值上
舉例:
有一個動物園,其中有很多動物, 找出其中所有的狗,進行獲取,在主方法中,飼養狗
import java.util.Arrays;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
Animal[] zoo = {
new Dog(),
new Dog(),
new Cat(),
new Wolf(),
new Wolf(),
new Wolf(),
new Monkey(),
new Monkey(),
new Monkey(),
new Monkey(),
new Monkey()
};
Dog[] dog = getDog(zoo);
//飼養所有的狗
for (int i = 0; i < dog.length; i++) {
dog[i].eat();
}
}
//方法一
// 方法名 : getDog 形式參數列表 Animal[] zoo 返回值類型 Dog[]
// public static Dog[] getDog(Animal[] zoo){
// //1 確定 動物園中有幾只狗
// int dogCount = 0;
// for (int i = 0; i < zoo.length; i++) {
// //判斷每只動物是否是狗
// if (zoo[i] instanceof Dog){
// dogCount++;
// }
// }
//
// //2 根據狗的個數確定狗窩的大小
// Dog[] dogsHouse = new Dog[dogCount];
//
// //3. 將所有的狗存儲到狗窩中
// int index = 0;
// for (int i = 0; i < zoo.length; i++) {
// if (zoo[i] instanceof Dog){
// //向下轉型
// dogsHouse[index] =(Dog) zoo[i];
// index++;
// }
// }
//
// //4 將狗窩返回
// return dogsHouse;
//
// }
//方法二
public static Dog[] getDog(Animal[] zoo){
//1 遍歷每一個動物 判斷是否為狗 是狗就存儲到狗窩中
// 創建一個狗窩 容量為 0
Dog[] dogHouse = new Dog[0];
for (int i = 0; i < zoo.length; i++) {
if (zoo[i] instanceof Dog){
//存儲到狗窩中
// 擴容
//dogHouse = dogHouseCopy(dogHouse);
dogHouse = Arrays.copyOf(dogHouse,dogHouse.length+1);
dogHouse[dogHouse.length-1] = (Dog) zoo[i];
}
}
return dogHouse;
}
//定義一個方法作用 是用於進行狗窩的擴容每次擴容 1
// public static Dog[] dogHouseCopy(Dog[] dogs){
// Dog[] newHouse = new Dog[dogs.length+1];
// //復制原來數組的元素
// for (int i = 0; i < dogs.length; i++) {
// newHouse[i] = dogs[i];
// }
// return newHouse;
// }
}
//動物類
class Animal{
public void eat(){
System.out.println("動物吃");
}
public void sleep(){
System.out.println("動物睡覺");
}
}
//狗類
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗汪汪汪的吃肉");
}
//特有的方法
public void shout(){
System.out.println("狗汪汪汪的叫");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("貓喵喵的吃魚");
}
//特有的功能
public void catchMouse(){
System.out.println("貓抓老鼠");
}
}
//猴子
class Monkey extends Animal{
@Override
public void eat() {
System.out.println("猴子吃桃");
}
}
//狼
class Wolf extends Animal{
@Override
public void eat() {
System.out.println("狼吃羊");
}
}
多態的好處
1.屏蔽⼦類之間的差異性
2.增強了⽅法的通⽤性
3.利於程序的擴展