1. 构造函数
当写一个java类的时候,如果没有给出该类的任何构造函数,那么会默认有有一个无参数的构造器。在获取类的实例的时候,可以调用无参构造函数。
public class Test {
public static void main(String[] args) {
Test t = new Test();
}
}
但是,若在声明类的时候给出了构造函数,则默认的构造函数无效。想声明该类对象,则必须调用这个类明确给出的构造函数中的某一个。
public class Test {
public Test(int i){
}
public static void main(String[] args) {
Test t = new Test(2);
}
}
如果还是强行调用默认的构造函数,就相当于是调用一个没有声明的方法,就会报错。
注意:类的构造器也是静态方法,虽然构造方法前面没有加static关键字。
2. 构造函数的其他特点
① 构造函数必须与类的名字相同;
② 每个类可以有多个构造器;
③ 构造函数总是伴随着new操作一起调用,且不能由程序的编写者直接调用,必须由系统调用;
④ 构造函数的主要作用是完成对象的初始化工作。
3. 继承之子类调用父类构造器
Java中声明的类只可以有一个直接父类,不像c++中单个类可以同时继承来自于两个父类。
在java中,当一个类继承自其父类之后,可以在该子类内调用父类所有没有声明为private的方法和变量。当声明一个子类对象的时候,必须在其构造方法内部显示或隐式地调用344其父类中的构造器。
情况1:父类和子类都没有显示写出其构造函数,则声明子类对象的时候是隐式地调用子类和父类默认的无参数的构造方法。
class Base{ } public class Test extends Base{ public static void main(String[] args) { Test t = new Test(); } }
情况2:父类和子类中都是无参构造器。这与情况1一样,无需在子类的构造器中显示调用子类的构造器。
class Base{ public Base(){ System.out.println("base1"); } } public class Test extends Base{ public Test(){ System.out.println("test"); } public static void main(String[] args) { Test t = new Test(); } }
运行结果如下:
情况3:父类中有无参构造器也有有参的构造器,子类中有无参的,也有有参数的构造器。则默认调用父类的无参构造器,子类也可以显示调用父类的有参构造器。
class Base{
public Base(){
System.out.println("base 无参");
}
public Base(int i){
System.out.println("base 有参");
}
}
public class Test extends Base{
public Test(int i){
System.out.println("test 有参,但是默认调用父类无参");
}
public Test(){
System.out.println("test");
}
public Test(int i,int j){
super(i);
System.out.println("test 有参,但是显示调用父类有参");
}
public static void main(String[] args) {
Test t = new Test();
System.out.println("------");
Test t1 = new Test(1);
System.out.println("------");
Test t2 = new Test(1,2);
}
}
运行结果如下:
情况4:父类中没有无参构造器,子类中的构造器则必须显示调用父类的构造器。如果子类构造器中没有显示调用父类的构造器,则会报错。
class Base{
public Base(int i){
System.out.println("base 有参");
}
}
public class Test extends Base{
/*父类中没有无参的构造器,子类需要显示调用父类的有参构造器才可以*/
public Test(int i){
super(i);//没有这一行,代码将报错
System.out.println("test 有参,但是默认调用父类无参");
}
public static void main(String[] args) {
Test t = new Test();
System.out.println("------");
Test t1 = new Test(1);
}
}
总之,如果父类中有无参构造器(不管是默认还是显示),则子类构造器中可以显示调用父类中个某个有参构造器或无参构造器,如果没有显示调用,则默认子类调用父类的无参构造器。如果父类中没有无参构造器,则在父类中必须显示调用父类的某个有参构造器。因为一旦父类中声明有构造器,则其默认的无参构造器则无效。