zoukankan      html  css  js  c++  java
  • 2020.7.21

    一、今日学习内容

       1、多态变化

        (1)Java中多态的实现

                Java中多态的体现具体表现在方法的重载和覆盖上,覆盖的概念,主要是指子类重写了父类中的方法。

                示例:子类重写父类中的方法

    public class Father{
          public void say() {
              System. out.println("father say()");
          }
    }
    class Son extends Father{
          public void say(){
               System. out.println("son say()");
          }
    }

            子类重写父类中的方法,即子类中的方法与父类中的方法保持一致。 但是方法的修饰符一定要大于等于父类中方法的修饰符。
             此时在子类中调用与父类相同的方法时,则调用的是子类的,并非父类的方法。

    public class Father{
          public void say() {
              System.out.println("father say()");
          }
           public static void main (String[]  args) {
               Son son=new Son() ;    
                son.say() ;
           }
    }
    class Son extends  Father{
               public void say() {
                   System.out.println("son say()") ;
              }
    }

           输出结果:son say()

            (2)类型检测——向上转型/向下转型

                向上转型是指父类对象的引用指向子类对象。向下转型是指在向上转型的基础上再次指向子类的对象。
               a.向上转型:父类  对象=new  子类()

                   示例:向上转型

    public class  Father{
           public void say() {
              System. out.println("father say()");
          }
          public static void main(String[] args) {
               //向上转型
               Father  son = new Son() ;
               son. say();
          }
    }
    class Son extends Father{
            public void say() {
                 System. out.println("son say()");
             }
    }

                    输出结果: son  say()

                   但是有时使用向上转型会丢失掉子类特有的方法,例如:

    public class Father{
         public void say() {
            System. out. println("father say()") ;
         }
         public static void main(String[] args) {
             //向上转型
             Father son= new Son() ;
             / /报错!
             son. sayMe () ;
         }
    }
    class Son extends Father{
            public void say() {
               System.out.println("son say()");
            }
            public void sayMe () {
                System. out.println("son sayMe()") ;
            }
    }

                会在编译时报错!

            b.向下转型:父类  对象1  = new  子类();

                                 子类  对象2=(子类)对象1;

                从这个格式可以看出,使用向下转型必须使用(类型)进行强转。

              示例:向下转型

    public class Father{
             public void say() {
                 System. out.println("father say()");
            }
            public static void main(String[] args) {
                //向上转型
                Father son= new Son() ;
               //向下转型
               Son son2 =(Son) son;
                son2.sayMe () ;
            }
    }
    class Son extends Father {
             public void say() {
               System. out.println("son say()");
             }
              public void sayMe () {
                  System. out.printin("son sayMe()") ;
              }
    }

                注:如果直接将父类强转成子类对象会报错!   例:

                        虽然在编译时没有错,但是在运行时会报错。

                 这是因为父类对象不能直接强转成子类对象。在实际开发中,凡是用到继承,我们应该会第一想到使用向上类型转换。
                现将向上转型总结如下。
                 (1)父类引用指向子类对象,子类引用不能指向父类对象。
                 (2)把子类对象直接赋给父类引用叫upcasting 向上转型,向.上转型不用强制转型,如Father f1 =new Son()。
                 (3)把指向子类对象的父类引用赋给子类引用叫向下转型( downcasting),要强制转型。如fl就是一个指向子类对象的父类引用,把fl赋给子类引用s1即                                      Son  s1= (Son) fl。其中,fl 前面的(Son)必须添加,进行强制转换。
                 (4) upcasting 会丢失子类特有的方法(下面有说明),但是子类overriding 父类的方法,子类方法有效。

       (3)动态绑定

               Java虚拟机调用一个类方法时,它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当虚拟机调用一个实例方法时,它会基于对象实际的类 型(只能在运行时得知)来选择所调用的方法,这就是动态绑定,是多态的一种。动态绑定为解决实际的业务问题提供了很大的灵活性,是-种非常优美的机制。

                动态绑定具体表现在向上转型上,因为只有在运行时才知道具体运行的是哪个实例。

               示例:动态绑定

    public class Father {
           public void say() {
              System. out.println("father say()") ;
           }
          public static void main(String[] args) {
              //向上转型
               Father son = new Son() ;
               son.say() ;
          }
    }
    class Son extends Father {
             public void say() {
                System.out.println("son say()");
              }
    }

               静态绑定:所谓静态绑定就是在程序编译时就绑定的,在Java中的变量都是静态绑定的,只有private、 static和final是静态绑定的。

    public class Father { 
          String name=" father";
          public static void say() {
              System. out.println("father say()");
          }
          public void say2() {
               System. out.printin("father say2()");
          }
          public static void main (String[] args) {
              Father f = new Son() ;
             //虽然是指向了Son的引用,但是变量在编译的时候就动态绑定了
             //所以输出的是father
             System. out. println(f.name) ;
             / /因为Father里面的say是static,
            / /编译时就静态绑定了,所以输出father say()
            f.say() ;
            //而say2不是static方法,f是由Son new 出来的,
            //执行的时候会执行new它的那个类的say2()方法,
           //所以输出son say2(), 这是java的多态性
           f.say2() ;
         }
    }
    class Son extends Father {
            String name="son";
            public static void say() {
               System. out.println("son say()");
            }
           public void say2() {
              System. out.println("son say2()");
          }
    }

               输出结果:father

                                father  say()

                               son  say2()

    二、遇到的问题

          对向下转型不是很理解

    三、明日计划

         明天继续学习第五章的内容

  • 相关阅读:
    交叉熵的数学原理及应用——pytorch中的CrossEntropyLoss()函数
    pytorch中如何使用DataLoader对数据集进行批处理
    Pytorch中的自动求导函数backward()所需参数含义
    Pytorch中的torch.cat()函数
    Pytorch中的squeeze()和unsqueeze()函数
    UBUNTU18.04安装网易云音乐并直接图标启动
    UBUNTU18.4环境下使用更好用的搜索引擎(无奈,只能起这样的标题)
    Ubuntu 18.04换国内源 中科大源 阿里源 163源 清华源
    共享栈
    C++(十七) — 宏代码、内联函数
  • 原文地址:https://www.cnblogs.com/wmdww/p/13357193.html
Copyright © 2011-2022 走看看