zoukankan      html  css  js  c++  java
  • 12)Java Constructor

    Constructor
     
         构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。
         构造器用来确保每个对象都会得到初始化。当对象被创建时,如果该类具有构造器,java就会在用户有能力操作对象之前自动调用相应的构造器,所以保证了初始化地进行。在java中创建和初始化被捆绑在了一起,两者不能分离。注意构造器没有返回值.
         定义一个Java类时。如果没有显式定义一个不带参数的构造函数但定义了一个带参数的构造函数,则不能再以不带参数的构造函数创建一个该类的实例:[即如果已经定义了一个构造函数(无论有无参数),编译器就不会帮你自动创建缺省构造函数].
    这里提到this关键字,它只能在方法内部使用,表示对“调用方法的那个对象”的引用。可以使用this关键字在构造器中调用构造器。例:
     
    Public class Flower{
          Static Test monitor=new Test();
          Int petalCount=0;
          String s=new String(“null”);
          Flower(int petals){petalCount=petals;}
          Flower(String ss){s=ss;}
          Flower(String s,int petals){
                This(petals);
                //This(s); 这里是不允许的,因为尽管可以用this调用一个构造器,但是不能调用2个
                This.s=s;
          }
    }

         所有类都是继承于Object的,在所有类实例化为对象的时候,必然会先调用Object的默认构造函数。static方法就是没有this的方法,static方法内部不能调用非静态方法。如果一个类的构造函数是静态的,那么它将无法调用Object的构造函数。因此构造函数不能声明为static类型。如果你想让一个类的对象只有指定的静态方法可以返回,你可以这样。 
      class   Test { 
              private   Test(){ }//私有构造方法,这样外部将无法创建此类的对象。联想单例模式   
              public static Test getInstance(){ 
                      return new Test();   //静态公共方法,返回Test的对象。 
              }  }

    (1) 类可以没有构造方法,但如果有多个构造方法,就应该要有默认的构造方法,否则在继承此类时,需要在子类中显式调用父类的某一个非默认的构造方法了。
    (2) 在一个构造方法中,只能调用一次其他的构造方法,并且调用构造方法的语句必须是第一条语句。
    (3)一个类继承了另一个类的内部类,因为超类是内部类,而内部类的构造方法不能自动被调用,这样就需要在子类的构造方法中明确的调用超类的构造方法。

    class C extends A.B {
          C() { 
                new A().super(); // 这一句就实现了对内部类构造方法的调用。
          }
    }
    构造方法也可这样写:
    C(A a) {
         a.super();
    } // 使用这个构造方法创建对象,要写成C c = new C(a); a是A的对象。

    -----------------------------------------------------------------易错题:
    class A {
          public int Avar;
          public A() {
                System.out.println("AAA");
                doSomething();
         }
          public void doSomething() {
                Avar = 1111;
                System.out.println("A.doSomething()");
         }
    }

    public class B extends A {
          public int Bvar = 2222;
          public B() {
                System.out.println("BBB");
                doSomething();
                System.out.println("Avar=" + Avar);
         }
          public void doSomething() {
                System.out.println("Bvar=" + Bvar);
         }
          public static void main(String[] args) {
                new B();
         }
    }
         顺序是这样得,首先生成B就得先生成A,所以调用A的构造器,输出AAA,然后调用方法dosomething,注意:A的该方法被B覆盖,而你生成的是B的对象,所以它调用B的方法,由于BVAR目前没有给定值,所以自动初始化为0;
         然后生成B对象,先初始化变量BVAR,然后调用构造器输出BBB,然后调用方法,这时BVAR已初始化,所以输出BVAR=2222,而对象A中变量AVAR由于没有调用对象A的方法dosomething,所以其值为0,则输出0
    全部输出就如下:
          AAA
          Bvar=0
          BBB
          Bvar=2222
          Avar=0
         注意:初始化顺序,当继承时,先生成超类对象,生成对象时,先生成静态变量,然后是一般变量,然后调用构造器!当所有超类对象生成后,生成本对象,顺序一样! 当方法被覆盖时,调用目前对象的方法!
  • 相关阅读:
    Leetcode 274.H指数
    Leetcode 273.整数转换英文表示
    Leetcode 264.丑数II
    Leetcode 260.只出现一次的数字III
    Leetcode 242.有效的字母异位词
    Leetcode 241.为运算表达式设计优先级
    Leetcode 240.搜索二维矩阵II
    Leetcode 239.滑动窗口最大值
    Leetcode 237.删除链表中的节点
    Leetcode 236.二叉树的最近公共祖先
  • 原文地址:https://www.cnblogs.com/weilf/p/4125659.html
Copyright © 2011-2022 走看看