多态的概述

image.png

多态的格式与使用

  1. package com.Demo11;
  2. /*
  3. 代码当中体现多态性,其实就一句话,父类引用指向子类对象
  4. 格式:
  5. 父类名称 对象名 = new 子类名称();
  6. 或者:
  7. 接口名称 对象名 = new 实现类名称();
  8. */
  9. public class DemoMain {
  10. public static void main(String[] args) {
  11. //使用态的写法
  12. //左侧父类的引用,指向了右侧子类的对象
  13. Fu obj = new Zi();
  14. obj.method();
  15. obj.methodFu();
  16. }
  17. }
  18. ========================================================================================================================================
  19. package com.Demo11;
  20. public class Fu {
  21. public void method(){
  22. System.out.println("父类共有方法");
  23. }
  24. public void methodFu(){
  25. System.out.println("父类独有方法");
  26. }
  27. }
  28. ========================================================================================================================================
  29. package com.Demo11;
  30. public class Zi extends Fu{
  31. public void method(){
  32. System.out.println("子类的共有方法");
  33. }
  34. public void methodZi(){
  35. System.out.println("子类独有方法");
  36. }
  37. }

多态中成员变量的使用特点

  1. package com.Demo11;
  2. /*
  3. 访问成员变量的两种方式:
  4. 1.直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有则向上找
  5. 2.间接通过成员方法访问成员变量,看该方法属于谁,优先用谁,没有则向上找
  6. */
  7. public class DemoMain {
  8. public static void main(String[] args) {
  9. //使用多态的写法,杜磊引用指向子类的对象
  10. Fu obj = new Zi();
  11. System.out.println(obj.num); //父 10
  12. // System.out.println(obj.age); //错误写法
  13. obj.showNum(); //子类没有覆盖重写 10
  14. }
  15. }
  16. ========================================================================================================================================
  17. package com.Demo11;
  18. public class Fu {
  19. int num = 10;
  20. public void method(){
  21. System.out.println("父类共有方法");
  22. }
  23. public void methodFu(){
  24. System.out.println("父类独有方法");
  25. }
  26. public void showNum(){
  27. System.out.println(num);
  28. }
  29. }
  30. ========================================================================================================================================
  31. package com.Demo11;
  32. public class Zi extends Fu{
  33. int num = 20;
  34. int age=30;
  35. public void method(){
  36. System.out.println("子类的共有方法");
  37. }
  38. public void methodZi(){
  39. System.out.println("子类独有方法");
  40. }
  41. }

多态中成员方法的使用特点

  1. package com.Demo11;
  2. /*
  3. 在多态的代码当中,成员方法的访问规则是:
  4. 看new的是谁,就看用谁,没有则向上找
  5. 口诀:编译看左边,运行看右边
  6. 对比一下:
  7. 成员变量:编译看左边,运行还看左边
  8. 成员方法:编译看左边,运行看右边
  9. */
  10. public class DemoMain {
  11. public static void main(String[] args) {
  12. Fu obj = new Zi();
  13. obj.method(); //父子都有,优先用子
  14. obj.methodFu(); //子类没有,父类有,向上找到父类
  15. }
  16. }
  17. ========================================================================================================================================
  18. package com.Demo11;
  19. public class Fu {
  20. int num = 10;
  21. public void method(){
  22. System.out.println("父类共有方法");
  23. }
  24. public void methodFu(){
  25. System.out.println("父类独有方法");
  26. }
  27. public void showNum(){
  28. System.out.println(num);
  29. }
  30. }
  31. ========================================================================================================================================
  32. package com.Demo11;
  33. public class Zi extends Fu{
  34. int num = 20;
  35. int age=30;
  36. public void method(){
  37. System.out.println("子类的共有方法");
  38. }
  39. public void methodZi(){
  40. System.out.println("子类独有方法");
  41. }
  42. }

使用多态的好处

image.png

对象的向上转型

image.png

  1. package com.Demo11;
  2. public class DemoMain {
  3. public static void main(String[] args) {
  4. //向上的转型就是fui引用指向子类对象
  5. Animal obj = new Cat();
  6. obj.eat();
  7. }
  8. }
  9. ========================================================================================================================================
  10. package com.Demo11;
  11. public abstract class Animal {
  12. public abstract void eat();
  13. }
  14. ========================================================================================================================================
  15. package com.Demo11;
  16. public class Cat extends Animal{
  17. @Override
  18. public void eat() {
  19. System.out.println("猫吃鱼");
  20. }
  21. }

对象的向下转型

image.png

  1. package com.Demo11;
  2. public class DemoMain {
  3. public static void main(String[] args) {
  4. //向上的转型就是父类引用指向子类对象
  5. Animal obj = new Cat();
  6. obj.eat();
  7. //向下转型,进行“还原”动作
  8. Cat cat = (Cat) obj;
  9. cat.catchMouse();
  10. //下面是错误的向下转型
  11. //本来new的时候是一只猫,现在非要当做狗
  12. //错误写法!编译不会报错,但是运行会报错
  13. //java.lang.ClassCastException
  14. Dog dog = (Dog) obj;
  15. }
  16. }
  17. ========================================================================================================================================
  18. package com.Demo11;
  19. public class Cat extends Animal{
  20. @Override
  21. public void eat() {
  22. System.out.println("猫吃鱼");
  23. }
  24. public void catchMouse(){
  25. System.out.println("猫抓老鼠");
  26. }
  27. }
  28. ========================================================================================================================================
  29. package com.Demo11;
  30. public class Dog extends Animal{
  31. @Override
  32. public void eat() {
  33. System.out.println("狗吃骨头");
  34. }
  35. }
  36. ========================================================================================================================================
  37. package com.Demo11;
  38. public abstract class Animal {
  39. public abstract void eat();
  40. }

用instanceof关键字进行判断

  1. package com.Demo11;
  2. /*
  3. 如何才能知道一个父类引用的对象,本来是什么子类?
  4. 格式:
  5. 对象 instanceof 类名称
  6. 这将会得到一个boolean值结果,也就是判断前面的对象你们那当后面类型的实例
  7. */
  8. public class DemoMain {
  9. public static void main(String[] args) {
  10. //向上的转型就是fui引用指向子类对象
  11. Animal obj = new Cat();
  12. obj.eat(); //猫吃鱼
  13. //如果希望调用子类特有方法,需要向下转型
  14. //判断一下父类引用obj本来是不是Dog
  15. if (obj instanceof Dog){
  16. Dog dog = (Dog) obj;
  17. dog.watchHouse();
  18. }
  19. //判断一下父类引用obj本来是不是Cat
  20. if(obj instanceof Cat){
  21. Cat cat = (Cat) obj;
  22. cat.catchMouse();
  23. }
  24. }
  25. }
  26. ========================================================================================================================================
  27. package com.Demo11;
  28. public class Dog extends Animal{
  29. @Override
  30. public void eat() {
  31. System.out.println("狗吃骨头");
  32. }
  33. public void watchHouse(){
  34. System.out.println("狗看门");
  35. }
  36. }
  37. ========================================================================================================================================
  38. package com.Demo11;
  39. public class Cat extends Animal{
  40. @Override
  41. public void eat() {
  42. System.out.println("猫吃鱼");
  43. }
  44. public void catchMouse(){
  45. System.out.println("猫抓老鼠");
  46. }
  47. }
  48. ========================================================================================================================================
  49. package com.Demo11;
  50. public abstract class Animal {
  51. public abstract void eat();
  52. }

接口多态的综合案例-笔记本USB接口

image.png
image.png

  1. package com.Demo12;
  2. public interface UsbInterface {
  3. public abstract void open(); //打开设备
  4. public abstract void close(); //关闭设备
  5. }
  6. ========================================================================================================================================
  7. package com.Demo12;
  8. public class Computer {
  9. public void powerOn(){
  10. System.out.println("电脑开机");
  11. }
  12. public void powerOff(){
  13. System.out.println("电脑关机");
  14. }
  15. //使用USB接口的方法,使用接口作为方法的参数
  16. public void useDevice(UsbInterface usb){
  17. usb.open(); //打开设备
  18. if(usb instanceof Mouse){ //一定要先判断
  19. Mouse mouse = (Mouse) usb; //向下转型
  20. mouse.click();
  21. }else if(usb instanceof KeyBoard){ //先判断
  22. KeyBoard keyboard =(KeyBoard) usb;
  23. keyboard.input();
  24. }
  25. usb.close(); //关闭设备
  26. }
  27. }
  28. ========================================================================================================================================
  29. package com.Demo12;
  30. public class Mouse implements UsbInterface{
  31. @Override
  32. public void open() {
  33. System.out.println("打开鼠标");
  34. }
  35. @Override
  36. public void close() {
  37. System.out.println("关闭鼠标");
  38. }
  39. public void click(){
  40. System.out.println("鼠标点击");
  41. }
  42. }
  43. ========================================================================================================================================
  44. package com.Demo12;
  45. public class KeyBoard implements UsbInterface{
  46. @Override
  47. public void open() {
  48. System.out.println("打开键盘");
  49. }
  50. @Override
  51. public void close() {
  52. System.out.println("关闭键盘");
  53. }
  54. public void input(){
  55. System.out.println("键盘输入");
  56. }
  57. }
  58. ========================================================================================================================================
  59. package com.Demo12;
  60. public class DemoMain {
  61. public static void main(String[] args) {
  62. //首先创建一个电脑类
  63. Computer computer = new Computer();
  64. computer.powerOn();
  65. //首先向上转型
  66. UsbInterface mouse = new Mouse();
  67. //参数是USB类型,我正好传递进去的就是USB鼠标
  68. computer.useDevice(mouse);
  69. //创建一个USB键盘
  70. KeyBoard keyboard = new KeyBoard(); //没有使用多态写法
  71. //参数是USB类型,我正好传递进去的是实现类对象
  72. computer.useDevice(keyboard); //正确写法!也发生了向上转型
  73. //使用子类对象,匿名对象,也可以
  74. // computer.useDevice(new KeyBoard()); //也是正确写法
  75. computer.powerOff();
  76. }
  77. }