Java 中对于polymorphism:多态的理解

面向对象三大特性:封装,继承和多态。

而其中最难理解的就是多态。

下面是个人再看了一些书籍,和一些博主的资料整理:

 把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。(这句话是我理解第三种方法的关键,请仔细阅读理解)

        对象的引用型变量是具有多态性的,因为一个引用型变量可以指向不同形式的对象,即:子类对象作为父类对象来使用。

举一个例子,在一个单位中,有职工employee,职工中又有少数是管理者manager,管理者中又有一部分是领导。若小明是管理者manager类的对象,他也可以被看做是employee的对象,即他也可以被看做是一个职工,他同时具备着职工的所有属性。


代码如下:

  1. public class testDuoTai {
  2. public static void main(String[] args) {
  3. Employee emp1= new Employee( "小明", 23, 1000); //emp1是Employee的对象
  4. System.out.println(emp1.getInfo());
  5. Employee emp2= new Manager( "小明", 23, 1000, 5000); //注意此处emp2是Manager类的对象
  6. System.out.println(emp2.getInfo());
  7. }
  8. }
  9. //定义一个父类
  10. class Employee
  11. {
  12. String name;
  13. int age;
  14. float salary;
  15. Employee(){};
  16. Employee(String name, int age, float sal)
  17. {
  18. this.name=name;
  19. this.age=age;
  20. this.salary=sal;
  21. }
  22. String getInfo()
  23. {
  24. return "职工姓名:"+name+ "年龄:"+age+ "工资:"+salary;
  25. }
  26. }
  27. //定义一个子类
  28. class Manager extends Employee
  29. {
  30. float allowance;
  31. Manager(String name, int age, float sal, float aa)
  32. {
  33. this.name=name;
  34. this.age=age;
  35. this.salary=sal;
  36. allowance=aa;
  37. }
  38. }

输出结果如下:

 

  1. 职工姓名:小明年龄:23工资:1000 .0
  2. 职工姓名:小明年龄:23工资:1000 .0

 

此案例中,充分体现了多态性。即子类的对象可以作为父类的对象来使用。

再来看一道牛客网专项练习题:

 

下面代码的输出是什么?

  1. public class Base
  2. {
  3. private String baseName = "base";
  4. public Base()
  5. {
  6. callName();
  7. }
  8. public void callName()
  9. {
  10. System. out. println(baseName);
  11. }
  12. static class Sub extends Base
  13. {
  14. private String baseName = "sub";
  15. public void callName()
  16. {
  17. System. out. println (baseName) ;
  18. }
  19. }
  20. public static void main(String[] args)
  21. {
  22. Base b = new Sub();
  23. }
  24. }

A null                  B  sub              C  base

正确答案:A


解析:本题与内部类无关系,去掉内部类后代码如下:

  1. public class Base {
  2. private String baseName = "base";
  3. public Base() {
  4. callName();
  5. }
  6. public void callName() {
  7. System.out.println(baseName);
  8. }
  9. public static void main(String[] args) {
  10. Base b = new Sub();
  11. }
  12. }
  13. class Sub extends Base {
  14. private String baseName = "sub";
  15. public void callName() {
  16. System.out.println(baseName);
  17. }
  18. }

        执行 Base b = new Sub();时由于多态 b编译时表现为Base类特性,运行时表现为Sub类特性,Base b = new Sub();不管是哪

种状态都会调用Base构造器执行 callName()方法;执行方法时,由于多台表现为子类特性,所以会先在子类是否有 callName();

此时子类尚未初始化(执行完父类构造器后才会开始执行子类),如果有就执行,没有再去父类寻找。

参考:https://blog.csdn.net/qq_25827845/article/details/50801035

猜你喜欢

转载自blog.csdn.net/weixin_41571493/article/details/80919784
今日推荐