Think in Java 构造函数_继承_super()_android_Dialog()_为何有些类没有构造函数自己体悟

  1. 首先是因为自己看到了去看了张龙老师的教程
    1.   里面说到关于 多态的一个很直观的体现就是:构造函数的不同
    2.   还有就是父类和子类之间的构造函数的调用关系
  2. 具体来说:子类继承父类,并且创建子类对象过程中
    1.   首先new 子类(无参)的过程之前有说过的(是没有继承的情况)
    2.   有继承的情况下,首先要执行调用子类的默认无参构造函数,执行里面的第一行语句:默认的隐式调用父类的默认的无参构造函数【觉得这句话不对,觉得应该是先加载的父类之后,可是怎么知道调用的就是父类的默认的无参构造函数呢?要是子类之命了是其他的构造函数,那应该是子类构造里面先执行 调用父类的构造函数】(前提是 父类目前只有一个默认的父类无参构造函数,可以写出来,也可以不写出来。要是父类中还有其他的有参构造函数的话,就必须将无参构造函数写出来)
      public class Children extends Father{
      
      
      
          
      
          public static void main(String[] args) {
      
              Children children=new Children();
      
              
      
          }
      
      }
      
      
      
      class Father{
      
          
      
          
      
          
      
      }
      //执行没有报错,可是怎么看出来子类的构造方法是调用了父类的默认无参构造函数了呢?

       

      1. public class Children extends Father {
        
        
        
            public static void main(String[] args) {
        
                Children children = new Children();
        
        
        
            }
        
        }
        
        
        
        class Father {
        
        
        
            /**
        
             * 若是执行了下面的语句,则说明父类的默认无参构造函数被调用
        
             */
        
            public Father() {
        
        
        
                System.out.println("Father 构造函数");
        
            }
        
        
        
        }//执行结果是:   Father 构造函数 证明子类new对象时候确实调用了父类的默认无参构造函数,但是是谁调用了父类的构造函数,new子类对象时候会调用子类的默认无参构造函数(因为这里new Children()没有传递参数,然后由子类的默认构造函数调用父类的构造函数)

         

         

        1. package gouzao;
          
          
          
          public class Children extends Father {
          
          
          
              public Children() {
          
          
          
                  System.out.println("Chilren 构造函数");
          
              
          
              
          
              }
          
              public static void main(String[] args) {
          
                  Children children = new Children();
          
          
          
              }
          
          }
          
          
          
          class Father {
          
          
          
              /**
          
               * 若是执行了下面的语句,则说明父类的默认无参构造函数被调用
          
               */
          
              public Father() {
          
          
          
                  System.out.println("Father 构造函数");
          
              }
          
          
          
              /**
          
               * 执行结果是:
          
               * Father 构造函数
          
                 Chilren 构造函数
          
               */
          
          }//说明先执行了父类的构造函数,再执行子类的构造函数

          yiwen:1-调用父类的构造函数就创建了父类的对象了吗?
            2.java虚拟机对这一段的加载机制是怎么样子的?

        2. 当然了,父类中可以有其他的   有参构造函数的,那么这时候子类调用的仍然是  是父类的  默认无参构造函数
      2. package gouzao;
        
        
        
        public class Children extends Father {
        
        
        
            public Children() {
        
        
        
                System.out.println("Chilren 构造函数");
        
            
        
            
        
            }
        
            public static void main(String[] args) {
        
                Children children = new Children();
        
        
        
            }
        
        }
        
        
        
        class Father {
        
        
        
            /**
        
             * 若是执行了下面的语句,则说明父类的默认无参构造函数被调用
        
             */
        
            public Father() {
        
        
        
                System.out.println("Father 构造函数");
        
            }
        
        
        
            
        
            /**
        
             * 当然了,父类中是可以写其他的有参构造函数的,那么这时候子类调用的是默认的无参构造函数
        
             * @param x
        
             */
        
            public Father(String x) {
        
        
        
                System.out.println(x);
        
            }
        
        
        
            
        
            /**
        
             * 执行结果是:
        
             * Father 构造函数
        
               Chilren 构造函数
        
             */
        
        }

         

      3. 另外我们知道默认的无参构造函数可以不写,那么我们隐藏父类的 无参构造试试:
        发现编译器报错:隐式的父类构造函数Father()没有被定义(也就是没有显式的写出来),必须显式地调用另外一个弗雷德构造函数。

        通俗的来说:张三进了一个帮派,帮派会默认的给他一个默认的师傅叫李四,当然了这个师傅还是不错,这个师傅平时可以出来也可以不出来,不出来的话呢,张三也可以默认找到他。当然有一天,有一个也叫李四的人出来了(成为新的李四师傅,之前的就是原来的李四师傅),这时候张三的原来的李四师傅要是出现的话呢,张三要是有什么不懂的还是去问原来的李四师傅,不会问现在的新的也叫李四的家伙。可是当原来的李四师傅不在的时候且帮派只有一个可以给张三提供给帮助的人的时候,当张三需要帮助的时候,帮派的默认系统会默认的把原来的李斯师傅找出来,现在呢,原来的李四是因为是默认不在的,张三有时候有急事找他帮忙他不在,这时候呢,帮派的默认系统本是要去找原来的李四师傅的,可是发现:哎,不是有一个新的李四师傅就是一直在你张三身边,张三你自己去问吧,我不给你找了,现成的你不用,你还要我找,你逗我吧!" 于是,,张三也可以随时向新的李四师傅请求帮助,当然是有代价的,比如这个新的李四师傅要求每次帮忙必须给一根烟(也就是父类有参构造函数的 参数),张三没得办法,因为原来的李四师傅不在(没有显式的定义)加上确实有急事在加上帮派系统不给他找原来的李四师傅(子类要创建对象,要调用父类的构造函数),于是呢,就带了一根烟来请新的李四师傅帮忙。也就是解决子类构造函数在调用父类的无参构造函数发现父类的无参构造函数隐藏了(没有显式定义的时候)的方法:在子类对应的构造函数中 通过super(参数)来调用父类的其他的构造函数,就像相当于在帮派中,要是张三有一根烟他可以去请新的李四师傅(因为新的李四师傅只要一根烟就肯帮忙),当然要是张三有两根烟的话,他也可以去请帮派中要两根烟就肯帮忙的人(当然这个人要显式存在,不是神龙见首不见尾的,即该构造函数要显式定义) 。
        public Children()
         //Implicit super constructor Father() is undefined. Must explicitly invoke another constructor
        package gouzao;
        
        
        
        public class Children extends Father {
        
        
        
            public Children() {
        
        
        
                //Implicit super constructor Father() is undefined. Must explicitly invoke another constructor
        
                System.out.println("Chilren 构造函数");
        
        
        
            }
        
        
        
            public static void main(String[] args) {
        
                Children children = new Children();
        
        
        
            }
        
        }
        
        
        
        class Father {
        
        
        
            /**
        
             * 隐藏父类的无参构造,发现编译器报错
        
             */
        
            /*
        
             * public Father() {
        
             * 
        
             * System.out.println("Father 构造函数"); }
        
             */
        
        
        
            /**
        
             * 当然了,父类中是可以写其他的有参构造函数的,那么这时候子类调用的是默认的无参构造函数
        
             * 
        
             * @param x
        
             */
        
            public Father(String x) {
        
        
        
                System.out.println(x);
        
            }
        
        
        
        
        
        }

         

      4. 当然最好的解决办法就是把那个默认原来的李四师傅给固定住,不让他一会消失一会隐藏(即显式定义,这样就张三不要每次找人问了,只要说出问题就可以有人自动解答,当然这个人就是原来的李四师傅,显式定义后就会一直默默做贡献)
        package gouzao;
        
        
        
        public class Children extends Father {
        
        
        
            public Children() {
        
        
        
                //Implicit super constructor Father() is undefined. Must explicitly invoke another constructor
        
                System.out.println("Chilren 构造函数");
        
        
        
            }
        
        
        
            public static void main(String[] args) {
        
                Children children = new Children();
        
        
        
            }
        
        }
        
        
        
        class Father {
        
        
        
            /**
        
             * 还是把原来的李四师傅固定住好
        
             */
        
            
        
              public Father() {
        
             
        
              System.out.println("Father 构造函数"); 
        
              }
        
             
        
        
        
            /**
        
             * 当然了,父类中是可以写其他的有参构造函数的,那么这时候子类调用的是默认的无参构造函数
        
             * 
        
             * @param x
        
             */
        
            public Father(String x) {
        
        
        
                System.out.println(x);
        
            }
        
        
        
        
        
        }

         

    3. 具体应用场景
      1.   继承Dialog()类的时候
        1. http://blog.itpub.net/25701553/viewspace-697932/
      2.   Android中 自定义一个控件继承 LinearLayout类
        1. http://zhidao.baidu.com/link?url=oioeyWDrki5D7CcUoxiwV3ZNc3hZX1Vkv8Rfh32XzNr25bPLlTQnGTMDr4kwQ2cWdd3iG91pS3RxsLU5csEgNa
           
      3.   问题一般都是要继承的父类中没有 定义 无参的构造函数,但是子类中却没有使用super调用父类的无参构造函数
    4. 扩展:为何有些类没有无参构造函数
      1.   Dialog类没有空构造方法原因,因为Dialog必须依托于一个组件而存在,我们的构造方法必然要指定这个Dialog的父亲是谁,空的构造方法怎么去指定这个父亲组件呢?
  3.   

你可能感兴趣的:(android)