• java基础知识(二)-----多态和构造函数


      一:前言

       最近由于面试了新浪公司,面试官问我的问题我都不知道,觉得自己好菜,所以最近决定再把java基础给搞一遍,真的觉得自己好菜。每天看一点,那个家伙说《java编程思想》最少要看三遍,我一遍都没看完。现在每次都写写自己的最新指导的知识点吧。努力!!!刚刚在一个群上说了下这,别人给我说了句话“你要提醒自己,所有的技术别人能学会的你迟早能学会,没什么大不了的”。记住

      二:内容

      (1):关于构造方法的问题

        我们每次写一个类中,都会说在类中加一个无参数的构造方法,我时常在想,这个无参数的构造函数有什么用,我一直很困惑,但是现在我可能明白了一点吧,由于那次看了下ArrayList的源码我才明白点,先上了ArrayList代码看看

      

     /**
         * Constructs an empty list with the specified initial capacity.
         *
         * @param   initialCapacity   the initial capacity of the list
         * @exception IllegalArgumentException if the specified initial capacity
         *            is negative
         */
        public ArrayList(int initialCapacity) {
        super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
        this.elementData = new Object[initialCapacity];
        }
    
        /**
         * Constructs an empty list with an initial capacity of ten.
         */
        public ArrayList() {
        this(10);
        }

    我自己也写了个测试了下如下:

     1 package thinker;
     2 public class ConstrutsDemo01 {
     3     public String a;
     4     public void find(){
     5         System.out.println("我的测试端");
     6     } 
     7     
     8     public ConstrutsDemo01(){
     9         this("5");
    10     }
    11     
    12     public ConstrutsDemo01(String a){
    13         this.a=a;
    14     }
    15     
    16     public static void main(String args[]){
    17         ConstrutsDemo01 c=new ConstrutsDemo01();
    18         ConstrutsDemo01 c2=new ConstrutsDemo01("1");
    19         System.out.println("无参数构造方法"+c.a);
    20         System.out.println("有参数的构造方法"+c2.a);
    21     }
    22 }

    这里给我的答案是,通过构造方使得我们既可以在实例化时传递参数,也可以不传递参数。好处显而易见吧。不知道这是不是需要构造函数的好处了!

    (二):多态机制的缺陷

    B:对于私有的方法无法覆盖,如下代码

     1 package thinker;
     2 
     3 public class Animal {
     4     private void fun(){
     5         System.out.println("我是动物的总称");
     6     }
     7     public static void main(String[] args) {
     8         Animal a=new Dog();
     9         a.fun();//结果是“我是动物的总称”
    10     }
    11 }
    12 
    13 
    14 package thinker;
    15 
    16 public class Dog extends Animal {
    17     public void fun(){
    18         System.out.println("动物:狗狗");
    19     }
    20     
    21 }

    所以我们得到的结论是“对于私有的方法我们没办法进行覆盖操作”

    B:多态的域域静态方法

      其实我也一样,刚刚了解多态的时候我也觉得,比如子类和父类中都有的相同变量那么如果调用这个变量,是否是和方法一样,调用得是子类的这个变量值了。显而我错了,只有普通的方法调用可以是多态的。如果你直接访问某个域,这个访问域就将在编译期进行解析如下:

    package thinker;
    
    public class Animal {
        public String name="动物";
        public void fun(String name){
            System.out.println("我是动物的总称"+name);
        }
        
    }
    package thinker;
    
    public class Dog extends Animal {
        public String name="猫";
        public void fun(String name){
            System.out.println("动物:"+name);
        }
        
        public String getName(){
            return super.name;
        }
        
        public static void main(String[] args) {
            Animal a=new Dog();
            Dog d=new Dog();
            System.out.println(a.name);//打印结果“动物”
            System.out.println("父类的name:"+d.getName()+"--子类的:"+d.name);//打印结果“父类的name:动物--子类的:猫”
        }
    }

    在《java编程思想》中是这样写的:“当Dog对象转型为Animal引用时,任何域访问操作都将由编译器解析,因此不是多态的”

    在说有关静态的方法:如果某个方法是静态的,它的行为就不具有多态性:

    package thinker;
    
    public class Animal {
        public String name="动物";
        public static void fun(String name){
            System.out.println("我是动物的总称:"+name);
        }
        public void fprint(){
            System.out.println("父类:非静态的类");
        }
        
    }
    package thinker;
    
    public class Dog extends Animal {
        public String name="猫";
        public static void fun(String name){
            System.out.println("动物:"+name);
        }
        public void fprint(){
            System.out.println("子类:非静态的类");
        }
        public static void main(String[] args) {
            Animal a=new Dog();
            a.fun("mouse");//结果“我是动物的总称mouse”
            a.fprint();//结果“子类:非静态的类”
        }
    }

    由此可以看出我们的fun()是静态的,调用打印的结果也是父类的方法,而fprint()方法是非静态的,调用打印结果是子类方法。可得:

    如果某个方法是静态的,则它的行为就不具有多态性

    三:有关实例化顺序

    package org.duotai;
    
    public class Computer {
        private int i=1;
        
        public void find(){
            System.out.println("Computer find()");
        }
    
        public Computer() {
            System.out.println("Computer find() be");
            System.out.println("构造方法"+i);
            find();//这里调用得其实是子类的方法,然而此时子类的数据(即i)还未实例化,所以在打印出的数据位0
            System.out.println("Computer find() af");
        }
        
        
    }
    
    
    
    
    package org.duotai;
    public class CPU  extends Computer{
        private int i=5;
        
        public CPU(int i){
            this.i=i;
            System.out.println("构造方法CPU.i="+i);
        }
        
        public void find(){
            System.out.println("方法CPU.i="+i);//由于此时未实例化所以值为0
        }
    }
    
    
    
    package org.duotai;
    public class DTDemo01 {
        public static void main(String args[]){
            new CPU(2);//调用
        }
    }

    在这里我们打印出的结果是:

    Computer find() be
    构造方法1
    方法CPU.i=0
    Computer find() af
    构造方法CPU.i=2

    可以看到“方法CPU.i=0”,所以我们得到,在父类实例化时调用方法,由于子类中的数据还未实例化,造成此种情况。

    实例化顺序:自己断点运行了下,发现在父类构造时还是先去初始化定义的变量,再来执行的构造方法内的内容。

     *******************************************

    姓名:耗子

    名言:机会都是留给有准备的人,GO!

    ******************************************

  • 相关阅读:
    python gevent(协程模块)
    python基础之socket与socketserver
    python 使用 with open() as 读写文件
    Python logger模块
    python二维码操作:QRCode和MyQR入门
    常见的端口号及其用途
    python中hasattr()、getattr()、setattr()函数的使用
    mysql数据库自带数据库介绍
    关于BeautifulSoup4 解析器的说明
    学习opencv(1)
  • 原文地址:https://www.cnblogs.com/wuhao1991/p/4071868.html
Copyright © 2020-2023  润新知