父类引用指向子类对象

灰太狼 2022-05-09 08:40 337阅读 0赞

最近学习装饰者模式的时候经常用到这个概念:

假如我们有一个父类Coffee 还有一个它的子类Suger那么我们将 Coffee coffee=new suger()就叫做父类引用指向子类对象;

总结一下它的特点吧:

1.子类suger对于父类的函数重写当使用父类coffee的时候会使用重写过后的函数

2.子类对于父类的重载函数使用父类引用的时候不能用,也就是只能用到父类引用里面定义有的函数

3.子类对于父类里面的变量假如重新赋值的话使用父类引用指向子类对象的话,coffee里面的变量也会变

还有就是再顺带总结一下父类以及子类的强制类型转换:(对于接口的操作与继承的关系是一样的)

  1. \*父类强制转换成子类在编译的时候不会报错但是运行的时候回抛出异常不能进行类型转换
  2. \* 在内存层面就是父类的内存空间小不能转化成内存空间更大的子类
  3. \* 但是子类可以转化成内存小的父类,转化是指的 大的部分也就是自己加上的方法不能用,但是还可以再
  4. \* 从父类转化成子类,此时就可以使用子类的方法了

下面就以代码的形式做一下总结:

  1. //先定义一个接口
  2. package test1;
  3. public interface Coffee {
  4. public int price=12;
  5. public void func1();
  6. public void func2();
  7. }
  8. //================定义父类
  9. package test1;
  10. public class Suger implements Coffee {
  11. private int price2=2;
  12. private int o=33;
  13. private int weight2=4;
  14. @Override
  15. public void func1() {
  16. System.out.println("func1");
  17. }
  18. @Override
  19. public void func2() {
  20. System.out.println("price是"+price2+" weight是"+weight2);
  21. }
  22. public void func3() {
  23. System.out.println("func3");
  24. }
  25. public static void main(String[] args) {
  26. Coffee coff=new Suger();//接口亦可以定义成父类引用的形式 在装饰者模式里面用到很多
  27. Suger sug=new Suger();
  28. Coffee coff2=(Coffee)sug;
  29. coff2.func1();
  30. Suger sug2=(Suger)coff2;
  31. sug2.func2();
  32. System.out.println("========上面是对于强制类型转换的操作");
  33. //接口的操作与继承的操作在这里都一样
  34. sug.func2();
  35. sug.func3();
  36. coff.func1();
  37. //coff.func3();
  38. }
  39. }
  40. //========================定义子类=============================================
  41. package test1;
  42. public class Test extends Suger {
  43. private int price2=5;
  44. private int weight2=6;
  45. @Override
  46. public void func1() {
  47. super.func1();
  48. }
  49. @Override
  50. public void func2() {
  51. System.out.println("price是"+price2+" weight是"+weight2);
  52. }
  53. //重载
  54. public void func3(int i) {
  55. System.out.println(i);
  56. }
  57. public void func4() {
  58. System.out.println("func4");
  59. }
  60. public static void main(String[] args) {
  61. //==========子类强制转换成父类对象还可以强制转换回子类对象
  62. Test test=new Test();
  63. Suger suger=(Suger)test;
  64. //suger.func4();// 强转过后子类独有的方法不能用了
  65. Test test2=(Test)suger;
  66. test2.func4();
  67. System.out.println("========================================");
  68. /*
  69. * 父类强制转换成子类在编译的时候不会报错但是运行的时候回抛出异常不能进行类型转换
  70. * 在内存层面就是父类的内存空间小不能转化成内存空间更大的子类
  71. * 但是子类可以转化成内存小的父类,转化是指的 大的部分也就是自己加上的方法不能用,但是还可以再
  72. * 从父类转化成子类,此时就可以使用子类的方法了
  73. * Exception in thread "main" func4
  74. java.lang.ClassCastException: test1.Suger cannot be cast to test1.Test
  75. at test1.Test.main(Test.java:39)
  76. */
  77. //Suger suger11=new Suger();
  78. //Test test3=(Test)suger11;
  79. //Suger suger12=(Suger)test3;
  80. //test3.func4();
  81. //suger11.func4();错误
  82. Suger sug=new Test();
  83. Test tes=new Test();
  84. sug.func1();
  85. sug.func2();//方法二进行过重载
  86. sug.func3();
  87. //sug.func3(666);错误因为在父类里面没有定义
  88. //sug.func4();
  89. System.out.println("============================tes===========================================");
  90. tes.func1();
  91. tes.func2();
  92. tes.func3(100000);
  93. tes.func4();
  94. //System.out.println(o);//private不可见
  95. }
  96. }

输出结果:

  1. 父类Suger
  2. func1
  3. price2 weight4
  4. ========上面是对于强制类型转换的操作
  5. price2 weight4
  6. func3
  7. func1
  8. 子类Test
  9. func4
  10. ========================================
  11. func1
  12. price5 weight6
  13. func3
  14. ============================tes===========================================
  15. func1
  16. price5 weight6
  17. 100000
  18. func4

发表评论

表情:
评论列表 (有 0 条评论,337人围观)

还没有评论,来说两句吧...

相关阅读