多态和抽象类

1. 多态

生活中的多态:指同一个动作,因为环境的不同,产生不一样的效果 程序中的多态:指同一段代码,因为实参的不同,产生不一样的效果 多态的实现方式: 1.父类作为形参 实参为子类类型 2.父类作为返回值 实际返回值类型为子类

  1. package com.qfedu.test1;
  2. /**
  3. * 父类:宠物类
  4. * @author WHD
  5. *
  6. */
  7. public class Pet {
  8. private String name;
  9. private int health;
  10. private int love;
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public int getHealth() {
  18. return health;
  19. }
  20. public void setHealth(int health) {
  21. this.health = health;
  22. }
  23. public int getLove() {
  24. return love;
  25. }
  26. public void setLove(int love) {
  27. this.love = love;
  28. }
  29. public void print() {
  30. System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
  31. }
  32. public void toHospital() {
  33. System.out.println("宠物看病");
  34. }
  35. @Override
  36. public String toString() {
  37. return "name=" + name + ", health=" + health + ", love=" + love + "]";
  38. }
  39. }
  1. package com.qfedu.test1;
  2. /**
  3. * 狗类
  4. * 名字
  5. * 健康值
  6. * 爱心值
  7. * 品种
  8. * 打印狗狗信息
  9. * @author WHD
  10. *
  11. */
  12. public class Dog extends Pet{
  13. private String strain;
  14. public String getStrain() {
  15. return strain;
  16. }
  17. public void setStrain(String strain) {
  18. this.strain = strain;
  19. }
  20. public Dog() {}
  21. public void toHospital() {
  22. System.out.println("狗狗看病,吃药,吃骨头,健康值恢复了");
  23. this.setHealth(100);
  24. }
  25. @Override
  26. public String toString() {
  27. String str = super.toString();
  28. return "Dog [strain=" + strain + ","+ str;
  29. }
  30. }
  1. package com.qfedu.test1;
  2. /**
  3. * 企鹅类
  4. * 名字
  5. * 健康值
  6. * 爱心值
  7. * 性别
  8. * 打印信息
  9. * @author WHD
  10. *
  11. */
  12. public class Penguin extends Pet{
  13. private String sex;
  14. public String getSex() {
  15. return sex;
  16. }
  17. public void setSex(String sex) {
  18. this.sex = sex;
  19. }
  20. public Penguin() {}
  21. public void toHospital() {
  22. System.out.println("企鹅看病,打针,疗养,吃鱼,健康值恢复了");
  23. this.setHealth(100);
  24. }
  25. }
  1. package com.qfedu.test1;
  2. /**
  3. * 多态 多种形态
  4. *
  5. * 生活中的多态:指同一个动作,因为环境的不同,产生不一样的效果
  6. * 程序中的多态:指同一段代码,因为实参的不同,产生不一样的效果
  7. * 多态的实现方式:
  8. * 1.父类作为形参 实参为子类类型
  9. * 2.父类作为返回值 实际返回值为子类类型
  10. * 需求:
  11. * 1.在原来宠物系统的基础上,添加给宠物看病的功能
  12. * 2.添加开业抽奖送宠物的活动
  13. * @author WHD
  14. */
  15. public class Test {
  16. public static void main(String[] args) {
  17. Master zhaosi = new Master();
  18. Dog dog = zhaosi.giveDog();
  19. System.out.println(dog);
  20. Penguin p = zhaosi.givePenguin();
  21. System.out.println(p.getName());
  22. System.out.println(p.getHealth());
  23. System.out.println(p.getLove());
  24. System.out.println(p.getSex());
  25. System.out.println("========================================");
  26. // 父类引用 指向子类对象
  27. // 多态 向上转型 此时可以调用子类重写父类的方法 和 父类访问权限允许的方法
  28. // 不能调用子类独有的方法 如果需要调用则需要向下转型
  29. Pet pet1 = zhaosi.give("一等奖");
  30. System.out.println(pet1.getName());
  31. System.out.println(pet1.getHealth());
  32. System.out.println(pet1.getLove());
  33. Penguin p1 = (Penguin)pet1;
  34. System.out.println(p1.getSex());
  35. System.out.println("==========================================");
  36. Pet pet2 = new Penguin();
  37. int a = 20;
  38. double b = a;
  39. }
  40. }

2. 向上、向下转型

1.向上转型 Pet pet = new Dog(); 此时可以调用子类重写父类的方法 和继承父类的方法 不能访问子类独有的方法

2.向下转型 向下转型是指 将 指向子类对象的父类引用 转换为子类类型 而不是直接将一个父类类型强制转换为子类

Dog dog = (Dog)pet;

此时可以调用子类独有的方法 以及继承父类、重写父类的方法

  1. package com.qfedu.test2;
  2. import com.qfedu.test1.Dog;
  3. import com.qfedu.test1.Penguin;
  4. import com.qfedu.test1.Pet;
  5. /**
  6. * 向上、向下转型
  7. * 1.向上转型 Pet pet = new Dog();
  8. * 此时可以调用子类重写父类的方法 和继承父类的方法 不能访问子类独有的方法
  9. * 2.向下转型
  10. * 向下转型是指 将 指向子类对象的父类引用 转换为子类类型
  11. * 而不是直接将一个父类类型强制转换为子类
  12. * Dog dog = (Dog)pet;
  13. * 此时可以调用子类独有的方法 以及继承父类、重写父类的方法
  14. * @author WHD
  15. *
  16. */
  17. public class TestPet {
  18. public static void main(String[] args) {
  19. // ctrl + shift + o 导入本类中所需要的所有包
  20. Pet pet = new Dog();
  21. pet.setHealth(100);
  22. pet.setLove(100);
  23. pet.setName("大黄");
  24. Dog dog = (Dog) pet;
  25. dog.setStrain("金毛");
  26. Pet pet1 = new Pet();
  27. // 在实际类型转换的过程中 我们会使用instanceof关键字判断类型是否可以正确转换
  28. // 对象名 instanceof 类名 表示判断左侧的对象是否属于右侧的类型 返回值为布尔类型的
  29. if(pet1 instanceof Penguin) {
  30. Penguin p1 = (Penguin) pet1; // 这种将报类型转换异常 ClassCastException
  31. }else {
  32. System.out.println("类型不匹配");
  33. }
  34. System.out.println("程序结束");
  35. }
  36. }

3. instanceof关键字

对象名 instanceof 类名 表示判断左侧的对象是否属于右侧的类型 返回值为布尔类型的

  1. package com.qfedu.test3;
  2. import com.qfedu.test1.Dog;
  3. public class Person {
  4. private String name;
  5. private String idCard;
  6. public String getName() {
  7. return name;
  8. }
  9. public void setName(String name) {
  10. this.name = name;
  11. }
  12. public String getIdCard() {
  13. return idCard;
  14. }
  15. public void setIdCard(String idCard) {
  16. this.idCard = idCard;
  17. }
  18. public Person() {
  19. }
  20. public Person(String name, String idCard) {
  21. this.name = name;
  22. this.idCard = idCard;
  23. }
  24. public boolean equals(Object obj) {
  25. if(this == obj) {
  26. return true;
  27. }
  28. if(obj instanceof Person) {
  29. Person p1 = (Person) obj;
  30. if(this.getName().equals(p1.getName()) && this.getIdCard().equals(p1.getIdCard())) {
  31. return true;
  32. }
  33. }
  34. return false;
  35. }
  36. public static void main(String[] args) {
  37. Person p1 = new Person("赵四", "12457332597891232321");
  38. Person p2 = new Person("赵四", "12457332597891232321");
  39. Dog dog = new Dog();
  40. dog.setName("大黄");
  41. dog.setHealth(100);
  42. dog.setLove(100);
  43. dog.setStrain("金毛");
  44. System.out.println(p1.equals(dog));
  45. System.out.println(p1.equals(p2));
  46. }
  47. }

4. 抽象类

1.抽象方法没有方法体 必须存在于抽象类中 抽象方法和抽象类都必须使用abstract修饰 2.抽象类不能直接new对象 必须通过new子类对象的方式创建 多态向上转型的方式 3.子类必须重写父类的抽象方法 除非子类也是抽象类 4.抽象类中可以书写普通方法 普通属性 构造方法 5.可以书写静态方法 静态方法可以被继承 不能被重写 6.抽象类实现多态与之前一致

  1. package com.qfedu.test5;
  2. /**
  3. * 门类
  4. * 因为门的具体的类别不确定 所以门的行为无法具体描述
  5. * 但是 只要是门 都能开和关
  6. * @author WHD
  7. *
  8. */
  9. public abstract class Door {
  10. public abstract void open();
  11. public abstract void close();
  12. }
  1. package com.qfedu.test5;
  2. public class CommonDoor extends Door{
  3. @Override
  4. public void open() {
  5. System.out.println("普通门开门,插入钥匙,轻轻一转,门开了,吱~");
  6. }
  7. @Override
  8. public void close() {
  9. System.out.println("普通门关门,咣当一声,手动关门");
  10. }
  11. }
  1. package com.qfedu.test5;
  2. public class SecurityDoor extends Door{
  3. @Override
  4. public void open() {
  5. System.out.println("防盗门开门,插入钥匙,输入密码,指纹+视网膜识别,门开了");
  6. }
  7. @Override
  8. public void close() {
  9. System.out.println("防盗门关门,红外线扫描障碍,自动关闭");
  10. }
  11. }
  1. package com.qfedu.test5;
  2. public class Person {
  3. // public void openCommonDoor(CommonDoor cd) {
  4. // cd.open();
  5. // }
  6. //
  7. // public void closeCommonDoor(CommonDoor cd) {
  8. // cd.close();
  9. // }
  10. //
  11. // public void openSecurityDoor(SecurityDoor sd) {
  12. // sd.open();
  13. // }
  14. //
  15. // public void closeSecurityDoor(SecurityDoor sd) {
  16. // sd.close();
  17. // }
  18. public void openDoor(Door door) {
  19. door.open();
  20. }
  21. public void closeDoor(Door door) {
  22. door.close();
  23. }
  24. public Door buyDoor(double money) {
  25. if(money > 2000) {
  26. return new SecurityDoor();
  27. }else {
  28. return new CommonDoor();
  29. }
  30. }
  31. public static void main(String[] args) {
  32. Person p1 = new Person();
  33. Door door1 = new CommonDoor();
  34. p1.openDoor(door1);
  35. Door door2 = new SecurityDoor();
  36. p1.openDoor(door2);
  37. p1.closeDoor(door1);
  38. p1.closeDoor(door2);
  39. }
  40. }