day12 面向物件(下) PQ
一、三大特性之多型(polymorphism)
1、多型的簡介
(1)概念
? 單態:這個物件只有唯一的一種狀態
? Student s = new Student();
? 多型:這個物件存在多種狀態, 是指同一行為,具有多個不同表現形式,
(2)多型實作的前提
? 1)要有繼承或者實作的關系
? 2)方法的重寫(如果沒有方法重寫,格式不會報錯,這樣的多型是沒有任何意義)
? 3)父類的參考指向子類物件(父new子)或者父介面的參考指向實作類物件(父介面new實作類)
2、多型的體現
(1)多型體現的格式
父型別別 變數名 = new 子類物件();
變數名.方法名();
eg:
Animal dog = new Dog();
dog.eat();
(2)多型思想下成員的特點
1)實體變數
? 物件被什么資料型別所修飾,這個變數就會呼叫誰的實體變數
//父類:SuperClass
public class SuperClass {
int num = 10;
}
//子類:SubClass
public class SubClass extends SuperClass {
int num = 20;
}
//測驗類:PolyDemo02
public class PolyDemo02 {
public static void main(String[] args) {
//父new父
SuperClass superC = new SuperClass();
System.out.println(superC.num);//10
//子new子
SubClass subC = new SubClass();
System.out.println(subC.num);//20
System.out.println("===================");
//利用多型創建物件
SuperClass sc = new SubClass();
System.out.println(sc);//com.atguigu.poly.demo02.SubClass@15db9742 子類地址值
System.out.println(sc.num);//10
}
}
2)實體方法
? 先看父類中是否有這個方法,如果有,執行子類重寫后的方法;如果沒有,編譯報錯
//父類:SuperClass
public class SuperClass {
public void method () {
System.out.println("父類的實體方法");
}
}
//子類:SubClass
public class SubClass extends SuperClass {
public void method () {
System.out.println("子類重寫后的實體方法");
}
}
//測驗類:PolyDemo04
public class PolyDemo04 {
public static void main(String[] args) {
//父new父
SuperClass superC = new SuperClass();
System.out.println(superC); //com.atguigu.poly.demo04.SuperClass@15db9742
superC.method();//父類的實體方法
System.out.println("==============");
//子new子
SubClass subC = new SubClass();
System.out.println(subC);//com.atguigu.poly.demo04.SubClass@6d06d69c
subC.method();//父類的實體方法
System.out.println("==============");
//父new子
SuperClass sc = new SubClass();
System.out.println(sc);//com.atguigu.poly.demo04.SubClass@7852e922
sc.method();//父類的實體方法
}
}
3)構造器
? 和原來一樣
//父類:SuperClass
public class SuperClass {
public SuperClass () {
System.out.println("父類的構造器");
}
}
//子類:SubClass
public class SubClass extends SuperClass {
public SubClass(){
//super(); 此處隱藏了JVM提供的super()
System.out.println("子類的構造器");
}
}
//測驗類PolyDemo03
public class PolyDemo03 {
public static void main(String[] args) {
//父new父
SuperClass superC = new SuperClass();//父類的構造器
System.out.println("================");
//子new子
SubClass subC = new SubClass();//父類的構造器 子類的構造器
System.out.println("================");
// 父new子
SuperClass sc = new SubClass();//父類的構造器 子類的構造器
System.out.println(sc); //com.atguigu.poly.demo03.SubClass@15db9742
}
}
3、多型的好處和弊端
(1)多型的好處
- 宣告方法時,不再將形參寫具體的參考資料型別,直接寫父類的型別或者父類介面的型別
- 物件陣列的應用
//Student類
public class Student {
private String name;
private int 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 Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
//重寫系統中自帶的toString方法
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
//測驗類:PolyDemo05
public class PolyDemo05 {
public static void main(String[] args) {
Student s1 = new Student("張三",18);
Student s2 = new Student("李四",23);
Student s3 = new Student("錢五",43);
Student s4 = new Student("孫六",23);
//物件陣列
Student[] arr = {s1,s2,s3,s4};
printArr(arr);
}
//object為頂級父類,將其放置形參
private static void printArr(Object[] arr) {
for (int i = 0; i < arr.length; i++) {
Object obj = arr[i];
System.out.println(obj);
}
}
}
//運行結果
Student [name=張三, age=18]
Student [name=李四, age=23]
Student [name=錢五, age=43]
Student [name=孫六, age=23]
(2)多型的弊端及解決辦法
1)多型的弊端
? 在多型的情況下,物件無法呼叫自己的特有方法,只能呼叫子類改寫父類的方法,
2)多型的解決方法
? 解決多型的弊端,參考資料型別的型別轉換
| 型別轉換名稱 | 型別轉換方向 |
|---|---|
| 向上轉型(默認轉換方式) | 將子類的物件或者實作類的物件轉換為父類的型別或者父介面型別(多型) |
| 向下轉型(強制型別轉換) | 將父型別別或者父介面型別轉換為子型別別或者實作型別別 |
- 向下轉型(強制型別轉換)格式:
子型別別 物件名 = (子型別別)父型別別的物件;
eg:
Animal cat = new Cat(); //多型
Dog dog = (Dog)cat; //強轉
-
參考資料型別強制型別轉換時注意事項:
可能會發生ClassCastException:型別轉換例外
3)instanceof關鍵字的引入
? 強制轉換時易發生型別轉換例外,使用instanceof給參考變數做型別的校驗
- instanceof使用格式
變數名 instanceof 資料型別
eg:
c instanceof Cat
-
instanceof回傳值
instanceof為關系運算子,如果變數屬于該資料型別,回傳true;如果變數不屬于該資料型別,回傳false,
4、練習題:貓狗
1.定義動物類
屬性:年齡,顏色
行為:eat(String something)方法(無具體行為,不同動物吃的方式和東西不一樣,
something表示吃的東西)生成空參有參構造,set和get方法
2.定義狗類繼承動物類
行為:eat(String something)方法,看家lookHome方法(無引數)
3.定義貓類繼承動物類
行為:eat(String something)方法,逮老鼠catchMouse方法(無引數)
4.定義Person類
屬性:姓名,年齡
行為:keepPet(Dog dog,String something)方法
功能:喂養寵物狗,something表示喂養的東西
行為:keepPet(Cat cat,String something)方法
功能:喂養寵物貓,something表示喂養的東西
實作以上兩種行為,思考如何只寫一個方法?
生成空參有參構造,set和get方法
5.測驗以上方法
使用多型、強轉、instanceof等
//Animal類
public abstract class Animal {
private int age;
private String color;
//設定set()、get()方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//設定無參構造器和滿參構造器
public Animal(int age, String color) {
super();
this.age = age;
this.color = color;
}
public Animal() {
super();
}
//設定動物類的抽象方法
public abstract void eat(String something);
}
//Cat類 繼承 Animal類
public class Cat extends Animal{
//重寫父類eat方法
public void eat(String something) {
System.out.println(getAge() + "歲" + getColor() + "色的小貓正在吃" + something);
}
//逮老鼠方法
public void catchMouse () {
System.out.println(getAge() + "歲" + getColor() + "色的小貓正在逮老鼠");
}
//設定構造器
public Cat() {
super();
}
public Cat(int age, String color) {
super(age, color);
}
}
//Dog類 繼承 Animal類
public class Dog extends Animal{
//重寫父類抽象方法
@Override
public void eat(String something) {
System.out.println(getAge() + "歲" + getColor() + "色的小狗正在吃" + something);
}
public void lookHome(){
System.out.println(getAge() + "歲" + getColor() + "色的小狗正在看家");
}
//設定構造器
public Dog() {
super();
}
public Dog(int age, String color) {
super(age, color);
}
}
//Person類
public class Person {
//喂養狗和喂養貓的方法為方法的多載,可以直接使用多型的好處一:宣告方法時,不再將形參寫具體的參考資料型別,直接寫父類的型別或者父類介面的型別
/*// 喂養狗的方法
public void keepPet(Dog dog,String something) {
dog.eat(something);
}
// 喂養貓的方法
public void keepPet(Cat cat,String something) {
cat.eat(something);
}*/
public void keepPet (Animal a,String something) {
a.eat(something);
}
}
//測驗類:
public class PolyDemo06 {
public static void main(String[] args) {
//創建貓物件
Animal cat = new Cat(2,"白");
//創建狗的物件
Animal dog = new Dog(3,"黑");
//創建人物件
Person p = new Person();
// 呼叫飼養員的喂養貓的方法
p.keepPet(cat, "魚");
// 將多型形式的物件進行向下轉型
if (cat instanceof Cat) {
Cat c = (Cat)cat;
c.catchMouse();
}
//cat物件不屬于Dog,判斷回傳false
if (cat instanceof Dog) {
Dog d = (Dog)cat;
d.lookHome();
}
//Cat c = (Cat)dog;
//c.catchMouse();
System.out.println("==================");
// 呼叫飼養員喂養狗的方法
p.keepPet(dog, "骨頭");
}
}
二、匿名內部類
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/572.html
標籤:其他
下一篇:開源軟體存在漏洞導致系統崩潰
