多态和抽象类
1. 多态
生活中的多态:指同一个动作,因为环境的不同,产生不一样的效果 程序中的多态:指同一段代码,因为实参的不同,产生不一样的效果 多态的实现方式: 1.父类作为形参 实参为子类类型 2.父类作为返回值 实际返回值类型为子类
package com.qfedu.test1;/*** 父类:宠物类* @author WHD**/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 void print() {System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);}public void toHospital() {System.out.println("宠物看病");}@Overridepublic String toString() {return "name=" + name + ", health=" + health + ", love=" + love + "]";}}
package com.qfedu.test1;/*** 狗类* 名字* 健康值* 爱心值* 品种* 打印狗狗信息* @author WHD**/public class Dog extends Pet{private String strain;public String getStrain() {return strain;}public void setStrain(String strain) {this.strain = strain;}public Dog() {}public void toHospital() {System.out.println("狗狗看病,吃药,吃骨头,健康值恢复了");this.setHealth(100);}@Overridepublic String toString() {String str = super.toString();return "Dog [strain=" + strain + ","+ str;}}
package com.qfedu.test1;/*** 企鹅类* 名字* 健康值* 爱心值* 性别* 打印信息* @author WHD**/public class Penguin extends Pet{private String sex;public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Penguin() {}public void toHospital() {System.out.println("企鹅看病,打针,疗养,吃鱼,健康值恢复了");this.setHealth(100);}}
package com.qfedu.test1;/*** 多态 多种形态** 生活中的多态:指同一个动作,因为环境的不同,产生不一样的效果* 程序中的多态:指同一段代码,因为实参的不同,产生不一样的效果* 多态的实现方式:* 1.父类作为形参 实参为子类类型* 2.父类作为返回值 实际返回值为子类类型* 需求:* 1.在原来宠物系统的基础上,添加给宠物看病的功能* 2.添加开业抽奖送宠物的活动* @author WHD*/public class Test {public static void main(String[] args) {Master zhaosi = new Master();Dog dog = zhaosi.giveDog();System.out.println(dog);Penguin p = zhaosi.givePenguin();System.out.println(p.getName());System.out.println(p.getHealth());System.out.println(p.getLove());System.out.println(p.getSex());System.out.println("========================================");// 父类引用 指向子类对象// 多态 向上转型 此时可以调用子类重写父类的方法 和 父类访问权限允许的方法// 不能调用子类独有的方法 如果需要调用则需要向下转型Pet pet1 = zhaosi.give("一等奖");System.out.println(pet1.getName());System.out.println(pet1.getHealth());System.out.println(pet1.getLove());Penguin p1 = (Penguin)pet1;System.out.println(p1.getSex());System.out.println("==========================================");Pet pet2 = new Penguin();int a = 20;double b = a;}}
2. 向上、向下转型
1.向上转型 Pet pet = new Dog(); 此时可以调用子类重写父类的方法 和继承父类的方法 不能访问子类独有的方法
2.向下转型 向下转型是指 将 指向子类对象的父类引用 转换为子类类型 而不是直接将一个父类类型强制转换为子类
Dog dog = (Dog)pet;
此时可以调用子类独有的方法 以及继承父类、重写父类的方法
package com.qfedu.test2;import com.qfedu.test1.Dog;import com.qfedu.test1.Penguin;import com.qfedu.test1.Pet;/*** 向上、向下转型* 1.向上转型 Pet pet = new Dog();* 此时可以调用子类重写父类的方法 和继承父类的方法 不能访问子类独有的方法* 2.向下转型* 向下转型是指 将 指向子类对象的父类引用 转换为子类类型* 而不是直接将一个父类类型强制转换为子类* Dog dog = (Dog)pet;* 此时可以调用子类独有的方法 以及继承父类、重写父类的方法* @author WHD**/public class TestPet {public static void main(String[] args) {// ctrl + shift + o 导入本类中所需要的所有包Pet pet = new Dog();pet.setHealth(100);pet.setLove(100);pet.setName("大黄");Dog dog = (Dog) pet;dog.setStrain("金毛");Pet pet1 = new Pet();// 在实际类型转换的过程中 我们会使用instanceof关键字判断类型是否可以正确转换// 对象名 instanceof 类名 表示判断左侧的对象是否属于右侧的类型 返回值为布尔类型的if(pet1 instanceof Penguin) {Penguin p1 = (Penguin) pet1; // 这种将报类型转换异常 ClassCastException}else {System.out.println("类型不匹配");}System.out.println("程序结束");}}
3. instanceof关键字
对象名 instanceof 类名 表示判断左侧的对象是否属于右侧的类型 返回值为布尔类型的
package com.qfedu.test3;import com.qfedu.test1.Dog;public class Person {private String name;private String idCard;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getIdCard() {return idCard;}public void setIdCard(String idCard) {this.idCard = idCard;}public Person() {}public Person(String name, String idCard) {this.name = name;this.idCard = idCard;}public boolean equals(Object obj) {if(this == obj) {return true;}if(obj instanceof Person) {Person p1 = (Person) obj;if(this.getName().equals(p1.getName()) && this.getIdCard().equals(p1.getIdCard())) {return true;}}return false;}public static void main(String[] args) {Person p1 = new Person("赵四", "12457332597891232321");Person p2 = new Person("赵四", "12457332597891232321");Dog dog = new Dog();dog.setName("大黄");dog.setHealth(100);dog.setLove(100);dog.setStrain("金毛");System.out.println(p1.equals(dog));System.out.println(p1.equals(p2));}}
4. 抽象类
1.抽象方法没有方法体 必须存在于抽象类中 抽象方法和抽象类都必须使用abstract修饰 2.抽象类不能直接new对象 必须通过new子类对象的方式创建 多态向上转型的方式 3.子类必须重写父类的抽象方法 除非子类也是抽象类 4.抽象类中可以书写普通方法 普通属性 构造方法 5.可以书写静态方法 静态方法可以被继承 不能被重写 6.抽象类实现多态与之前一致
package com.qfedu.test5;/*** 门类* 因为门的具体的类别不确定 所以门的行为无法具体描述* 但是 只要是门 都能开和关* @author WHD**/public abstract class Door {public abstract void open();public abstract void close();}
package com.qfedu.test5;public class CommonDoor extends Door{@Overridepublic void open() {System.out.println("普通门开门,插入钥匙,轻轻一转,门开了,吱~");}@Overridepublic void close() {System.out.println("普通门关门,咣当一声,手动关门");}}
package com.qfedu.test5;public class SecurityDoor extends Door{@Overridepublic void open() {System.out.println("防盗门开门,插入钥匙,输入密码,指纹+视网膜识别,门开了");}@Overridepublic void close() {System.out.println("防盗门关门,红外线扫描障碍,自动关闭");}}
package com.qfedu.test5;public class Person {// public void openCommonDoor(CommonDoor cd) {// cd.open();// }//// public void closeCommonDoor(CommonDoor cd) {// cd.close();// }//// public void openSecurityDoor(SecurityDoor sd) {// sd.open();// }//// public void closeSecurityDoor(SecurityDoor sd) {// sd.close();// }public void openDoor(Door door) {door.open();}public void closeDoor(Door door) {door.close();}public Door buyDoor(double money) {if(money > 2000) {return new SecurityDoor();}else {return new CommonDoor();}}public static void main(String[] args) {Person p1 = new Person();Door door1 = new CommonDoor();p1.openDoor(door1);Door door2 = new SecurityDoor();p1.openDoor(door2);p1.closeDoor(door1);p1.closeDoor(door2);}}
