多态:多种形态
生活中的多态:同一个 *** 作 因为环境不同 产生不同的效果
代码中的多态:同一个方法,因为实际参数或者返回值的不同,产生不同的效果
多态是面向对象三大特征之一,在实际开发中,多态随处可见,多态是提高代码质量重要的手段之一。
多态的表现形式:
1.父类作为形参,实参为子类类型
2.父类作为返回值,实际返回值为子类类型
2.1 父类作为形参package com.qfedu.test3; public class Dog extends Pet{ private String strain; public String getStrain() { return strain; } public void setStrain(String strain) { this.strain = strain; } public Dog() {} public Dog(String name,int health,int love,String strain) { super(name, health, love); this.strain = strain; } @Override public void print() { super.print(); System.out.println("狗狗的品种是:" + strain); } public void toHospital() { super.toHospital(); System.out.println("狗狗看病,吃药,吃骨头,健康值恢复!"); this.setHealth(100); } }
package com.qfedu.test3; public class Penguin extends Pet{ private String sex; public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Penguin() {} public Penguin(String name,int health,int love,String sex) { super(name, health, love); this.sex = sex; } public void print() { super.print(); System.out.println("企鹅的性别是" + sex); } public void toHospital() { super.toHospital(); System.out.println("企鹅看病,打针,疗养,吃小鱼,健康值恢复!"); this.setHealth(100); } }
package com.qfedu.test3; public class Pet { private String name; private int health; private int love; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; } public int getLove() { return love; } public void setLove(int love) { this.love = love; } public Pet() {} public Pet(String name,int health,int love) { this.name = name; this.health = health; this.love = love; } public void toHospital() { System.out.println("宠物看病"); } void print() { System.out.println("宠物的名字是:" + name + ",健康值是:" + health); System.out.println("宠物的爱心值:" + love ); } }
package com.qfedu.test3; public class Master { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void cureWithDog(Dog dog) { if(dog.getHealth() < 60) { dog.toHospital(); }else { System.out.println("狗狗很健康,不需要看病!"); } } public void cureWithPenguin(Penguin penguin) { if(penguin.getHealth() < 60) { penguin.toHospital(); }else { System.out.println("企鹅很健康,不需要看病!"); } } // 观察以上我们写的两个方法?有没有什么不太好的地方? // 因为目前是按照一个宠物编写一个看病方法 // 这样的做法,以后随着系统的迭代更新,我们需要编写更多的方法 // 来应对系统中更多的宠物,这种写法不符合写代码的<开闭原则> // 开闭原则:对扩展开放,对修改源代码关闭 // 所以:我们应该编写一个"万能"的方法,可以实现给所有的宠物看病 // Pet pet = new Dog(); public void cure(Pet pet) { if(pet.getHealth() < 60) { pet.toHospital(); }else { System.out.println("宠物很健康,不需要看病!"); } } }
package com.qfedu.test3; public class Test1 { public static void main(String[] args) { Master zhaosi = new Master(); zhaosi.setName("赵四"); Dog dog = new Dog("大黄", 55, 20, "大金毛"); zhaosi.cureWithDog(dog); System.out.println(dog.getHealth()); Penguin p = new Penguin("大白", 20, 1, "雌"); zhaosi.cureWithPenguin(p); System.out.println(p.getHealth()); } }
package com.qfedu.test3; public class Test2 { public static void main(String[] args) { Master liuneng = new Master(); Dog dog = new Dog("大黄", 22, 10, "拉布拉多"); // 形参为父类 实参为子类 多态表现形式之一 // 继承的核心思想:子类是父类 子类与父类 是 is a 的关系 // 这里传入Dog类对象 是类型自动提升 子类自动提升为父类类型 // 多态向上转型,父类引用指向子类对象 // 此时可以调用的是子类重写父类的方法 // 以及继承自父类的方法 // 不能调用子类独有的方法 liuneng.cure(dog); System.out.println(dog.getHealth()); Penguin p = new Penguin("小白", 12, 12, "雌性"); liuneng.cure(p); System.out.println(p.getHealth()); } }2.2 父类作为返回值
package com.qfedu.test4; public class Cat extends Pet{ private String furColor; public String getFurColor() { return furColor; } public void setFurColor(String furColor) { this.furColor = furColor; } @Override public void toHospital() { super.toHospital(); System.out.println("猫咪看病,吃猫粮,打针,健康值恢复!"); setHealth(100); } }
package com.qfedu.test4; public class Master { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Dog giveDog(){ Dog dog = new Dog("大黄", 100, 100, "金毛"); return dog; } public Penguin givePenguin() { Penguin p = new Penguin("大白", 100, 100, "雌"); return p; } public Cat giveCat() { Cat cat = new Cat(); cat.setName("花花"); cat.setLove(100); cat.setHealth(100); cat.setFurColor("绿色"); return cat; } public Tiger giveTiger() { return new Tiger(); } // 观察以上代码 我们发现 这种写法依然不符合开闭原则 // 如果有其他的奖项 我们还要继续编写代码 应对新的奖项 // 所以我们应该编写一个方法 用于实现所有的奖项 public Pet give(String condition){ if(condition.equals("一等奖")) { Dog dog = new Dog("大黄", 100, 100, "金毛"); return dog; }else if(condition.equals("二等奖")) { Penguin p = new Penguin("大白", 100, 100, "雌"); return p; }else if(condition.equals("三等奖")) { Cat cat = new Cat(); cat.setName("花花"); cat.setLove(100); cat.setHealth(100); cat.setFurColor("绿色"); return cat; }else if(condition.equals("幸运奖")) { return new Tiger(); }else { System.out.println("谢谢!"); return null; } } }
package com.qfedu.test4; public class Test1 { public static void main(String[] args) { Master zhaosi = new Master(); zhaosi.setName("赵四"); // 多态向上转型 父类引用指向子类对象 // 此时当前对象可以调用的是子类重写父类的方法 // 以及继承自父类的方法 // 不能调用子类独有的方法 Pet dog = zhaosi.give("一等奖"); dog.print(); Pet penguin = zhaosi.give("二等奖"); penguin.print(); } }3. 引用数据类型转换
自动提升
手动下降
3.1 向上转型
多态向上转型 父类引用指向子类对象
此时当前对象可以调用的是子类重写父类的方法
以及继承自父类的方法
不能调用子类独有的方法
<父类型> <引用变量名> = new <子类型>();
package com.qfedu.test4; public class Test1 { public static void main(String[] args) { Master zhaosi = new Master(); zhaosi.setName("赵四"); // 多态向上转型 父类引用指向子类对象 // 此时当前对象可以调用的是子类重写父类的方法 // 以及继承自父类的方法 // 不能调用子类独有的方法 Pet dog = zhaosi.give("一等奖"); dog.print(); Pet penguin = zhaosi.give("二等奖"); penguin.print(); } }
3.2 向下转型
向上转型不能访问子类独有的方法,如需 访问,可以向下转型
强制类型转换
为了避免类型转换的错误 我们可以使用instanceof关键字判断类型
避免错误的产生
package com.qfedu.test5; public class Dog extends Pet{ private String strain; public String getStrain() { return strain; } public void setStrain(String strain) { this.strain = strain; } public Dog() {} public Dog(String name,int health,int love,String strain) { super(name, health, love); this.strain = strain; } @Override public void print() { super.print(); System.out.println("狗狗的品种是:" + strain); } public void toHospital() { super.toHospital(); System.out.println("狗狗看病,吃药,吃骨头,健康值恢复!"); this.setHealth(100); } public void playFlyDisc() { System.out.println("狗狗玩飞盘,很开心~"); } }
package com.qfedu.test5; public class Test1 { public static void main(String[] args) { Master zhaosi = new Master(); zhaosi.setName("赵四"); Pet pet1 = zhaosi.give("一等奖"); // 向上转型 pet1.print(); Dog dog = (Dog)pet1;// 向下转型 dog.playFlyDisc(); // 向下转型是将:指向子类对象的父类引用 转换为 子类类型 // 而不是 将一个父类引用父类对象转换为子类类型 // 当引用数据类型 强制类型转换 应该先使用instanceof关键字判断类型是否可以 正确转换 // 对象名 instanceof 类名 // 表示判断此对象是否属于此类型 如果是返回值为true 否则为false Pet pet2 = new Pet(); if(pet2 instanceof Dog) { Dog dog1 = (Dog) pet2; }else { System.out.println("类型错误,不能转换"); } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)