多态性的理解:

可以理解为一个事物的多种形态。

何为多态性:

  • 对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
  • 举例:

    1. Person p = new Man();
    2. Object obj = new Date();

    多态性的使用:虚拟方法调用

  • 有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
    总结:编译,看左边;运行,看右边。

    多态性的使用前提:

  • ① 类的继承关系

  • ② 方法的重写

    多态性的应用举例:

    举例一:
    1. public void func(Animal animal){//Animal animal = new Dog();
    2. animal.eat();
    3. animal.shout();
    4. }
    举例二: ```java public void method(Object obj){

}

  1. 举例三:
  2. ```java
  3. class Driver{
  4. public void doData(Connection conn){//conn = new MySQlConnection(); / conn = new OracleConnection();
  5. //规范的步骤去操作数据
  6. // conn.method1();
  7. // conn.method2();
  8. // conn.method3();
  9. }
  10. }

多态性使用的注意点:

  • 对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

    关于向上转型与向下转型:

  • 7.1 向上转型:多态

  • 7.2 向下转型:
    • 7.2.1 为什么使用向下转型:
      • 有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。如何才能调用子类特的属性和方法?使用向下转型。
    • 7.2.2 如何实现向下转型:使用强制类型转换符:()
    • 7.2.3 使用时的注意点:
      • ① 使用强转时,可能出现ClassCastException的异常。
      • ② 为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
    • 7.2.4 instanceof的使用:
      • ① a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
      • ② 如果 a instanceof A返回true,则 a instanceof B也返回true.其中,类B是类A的父类。
      • ③ 要求a所属的类与类A必须是子类和父类的关系,否则编译错误。\
    • 7.2.5 图示:image.png

面试题:

  • 8.1 谈谈你对多态性的理解?
    • ① 实现代码的通用性。
    • ② Object类中定义的public boolean equals(Object obj){ }
      JDBC:使用java程序操作(获取数据库连接、CRUD)数据库(MySQL、Oracle、DB2、SQL Server)
    • ③ 抽象类、接口的使用肯定体现了多态性。(抽象类、接口不能实例化)
  • 8.2 多态是编译时行为还是运行时行为?

好的例子

多态的好处

提高了代码的维护性(继承保证);提高了代码的扩展性
原代码,不易扩展:
(借用本代码,也进一步理解一下工具类

  1. //父类:动物类
  2. class Animal{
  3. public void eat(){
  4. System.out.println("eat");
  5. }
  6. public void sleep(){
  7. System.out.println("sleep");
  8. }
  9. }
  10. //猫类
  11. class Cat extends Animal{
  12. //方法重写
  13. public void eat(){
  14. System.out.println("狗吃肉");
  15. }
  16. //方法重写
  17. public void sleep(){
  18. System.out.println("狗坐着睡");
  19. }
  20. }
  21. //狗类
  22. class Dog extends Animal{
  23. public void eat(){
  24. System.out.println("猫吃鱼");
  25. }
  26. public void sleep(){
  27. System.out.println("猫趴着睡");
  28. }
  29. }
  30. //添加猪类
  31. class Pig extends Animal{ //----------note:老忘记写extends!!!!!!!!!!
  32. public void eat(){
  33. System.out.println("猪吃白菜");
  34. }
  35. public void sleep(){
  36. System.out.println("猪躺着睡");
  37. }
  38. }
  39. //针对动物操作的工具类
  40. class AnimalTool{
  41. private AnimalTool(){}//最好把工具类的构造方法私有,防止别人创建该类的对象。该类是工具类。
  42. //调用猫的功能
  43. public static void feedCat(Cat c){ //工具类,方法就写成static的,然后直接在测试类:工具类名.方法 使用。
  44. c.eat();
  45. c.sleep();
  46. }
  47. //调用狗的功能
  48. public static void feedDog(Dog d){
  49. d.eat();
  50. d.sleep();
  51. }
  52. //添加猪的,调用猪的功能
  53. public static void feedDog(Dog d){
  54. d.eat();
  55. d.sleep();
  56. }
  57. }
  58. /*测试类
  59. 测试类里面不放其他东西(如,定义其他方法)!只能是建对象,调方法。
  60. 所以新定义了个操作动物的工具类去放feedCat(),feedDog()方法。
  61. */
  62. class DuotaiTest{
  63. public static void main(String[] args){
  64. //我喜欢猫,我养3只猫
  65. Cat c= new Cat();
  66. Cat c2= new Cat();
  67. Cat c3= new Cat();
  68. AnimalTool.feedCat(c);
  69. AnimalTool.feedCat(c2);
  70. AnimalTool.feedCat(c3);
  71. //我喜欢狗,我养3只狗
  72. Dog d= new Dog();
  73. Dog d2= new Dog();
  74. Dog d3= new Dog();
  75. AnimalTool.feedDog(d);
  76. AnimalTool.feedDog(d2);
  77. AnimalTool.feesDog(d3);
  78. //我喜欢宠物猪
  79. //需要定义一个猪类,它继承自动物类,提供两个方法。且在工具类里添加方法。
  80. //我喜欢宠物兔、老虎、狼.....
  81. //若按上述添加猪的办法做,定义类,继承类,提供方法都是必须要的。
  82. //但是在工具类里面改过来改过去,不好。能否做到不改?
  83. //能。
  84. //见DuotaiTest2.java 中工具类的写法
  85. }
  86. }

改进后:
采用多态后,易于扩展。
重点在:用Fu f做形参接收参数,用Zi z的z做实参。有了父类引用指向子类。即动物类引用指向各具体的动物类。同时又有方法重写,运行的时候肯定是个各子类重写的方法在起作用。从而利用多态实现好的扩展性。

  1. /*
  2. 多态的扩展性
  3. */
  4. /*
  5. 程序输出结果:
  6. 狗吃肉
  7. 狗坐着睡
  8. 狗吃肉
  9. 狗坐着睡
  10. 狗吃肉
  11. 狗坐着睡
  12. ---------------
  13. 猫吃鱼
  14. 猫趴着睡
  15. 猫吃鱼
  16. 猫趴着睡
  17. 猫吃鱼
  18. 猫趴着睡
  19. ---------------
  20. 猪吃白菜
  21. 猪躺着睡
  22. */
  23. //父类:动物类
  24. class Animal{
  25. public void eat(){
  26. System.out.println("eat");
  27. }
  28. public void sleep(){
  29. System.out.println("sleep");
  30. }
  31. }
  32. //猫类
  33. class Cat extends Animal{
  34. public void eat(){
  35. System.out.println("狗吃肉");
  36. }
  37. public void sleep(){
  38. System.out.println("狗坐着睡");
  39. }
  40. }
  41. //狗类
  42. class Dog extends Animal{
  43. public void eat(){
  44. System.out.println("猫吃鱼");
  45. }
  46. public void sleep(){
  47. System.out.println("猫趴着睡");
  48. }
  49. }
  50. //添加猪类
  51. class Pig extends Animal{ //----------note:老忘记写extends!!!!!!!!!!
  52. public void eat(){
  53. System.out.println("猪吃白菜");
  54. }
  55. public void sleep(){
  56. System.out.println("猪躺着睡");
  57. }
  58. }
  59. //针对动物操作的工具类
  60. class AnimalTool{
  61. private AnimalTool(){}//最好把工具类的构造方法私有,防止别人创建该类的对象。该类是工具类。
  62. /*-------------改动-----------------------*/
  63. //注意:形参是Animal a,用动物接收。 到时候左边是 Fu f, 右边是Zi z, Fu f= Zi z
  64. public static void feedAnimal(Animal a){ //工具类,方法就写成static的,然后直接在测试类:工具类名.方法 使用。
  65. a.eat(); //成员方法:运行看右边:各子类的。( 不然干嘛方法重写)
  66. a.sleep();
  67. }
  68. }
  69. /*测试类
  70. 测试类里面不放其他东西(如,定义其他方法)!只能是建对象,调方法。
  71. 所以新定义了个操作动物的工具类去放feedCat(),feedDog()方法。
  72. */
  73. class DuotaiTest2{
  74. public static void main(String[] args){
  75. //我喜欢猫,我养3只猫
  76. Cat c= new Cat();
  77. Cat c2= new Cat();
  78. Cat c3= new Cat();
  79. AnimalTool.feedAnimal(c);
  80. AnimalTool.feedAnimal(c2);
  81. AnimalTool.feedAnimal(c3);
  82. System.out.println("---------------");
  83. //我喜欢狗,我养3只狗
  84. Dog d= new Dog();
  85. Dog d2= new Dog();
  86. Dog d3= new Dog();
  87. AnimalTool.feedAnimal(d);
  88. AnimalTool.feedAnimal(d2);
  89. AnimalTool.feedAnimal(d3);
  90. System.out.println("---------------");
  91. //我喜欢宠物猪
  92. //需要定义一个猪类,它继承自动物类,提供两个方法。且在工具类里添加方法。
  93. //我喜欢宠物兔、老虎、狼.....
  94. //若按上述添加猪的办法做,定义类,继承类,提供方法都是必须要的。
  95. //但是在工具类里面改过来改过去,不好。能否做到不改?
  96. //能。
  97. //猫、狗、猪...都是动物,feedAnimal(Animal a)参数接收动物
  98. Pig p= new Pig();
  99. AnimalTool.feedAnimal(p);
  100. }
  101. }

多态
1、多态:同一个对象,在不同时刻体现出来的不同状态。
2、多态的前提:
  1)要有继承关系或实现关系(接口);
  2)要有方法重写;
  3)要有父类或者父接口引用指向子类`Fu f= new Zi();
    注意:形参实参形式的(形参父类实参子类)。
3、多态的分类:
  1)具体类多态

  1. class Fu{}
  2. class Zi extends Fu{}
  3. Fu f= new Zi()//父类引用指向子类

2)抽象类多态(常用)

  1. abstract class Fu{}
  2. class Zi extends Fu{}
  3. Fu f= new Zi();//抽象父类引用指向子类
  1. 3)接口多态(常用)
  1. interface Fu{}
  2. class Zi implements Fu{}
  3. Fu f= new Zi();//父接口引用指向子类

多态中成员访问特点

  1. 如,Fu f= new Zi();//左父类右子类

重点:成员方法,运行时,结果为子类重写的成员方法的结果。

成员变量:编译看左边,运行看左边。
构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
成员方法:编译看左边,运行看右边。(方法重写的意义)
静态方法:编译看左边,运行看左边。静态和类相关,算不上重写,所以访问还是左边的。
提醒:理解这些的时候要记得继承啊方法重写它们存在的意义所在。就好理解啦。