声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2455|回复: 0

[其他相关] Java 构造方法之父子继承

[复制链接]
发表于 2014-12-25 16:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x

构造方法又叫构造函数,也可叫构造器。

含义:每一个类都有构造方法,构造方法与该类类名相同,没有返回值(只要调用构造函数就必须出现在new后面,如果不用new,在eclipse里面会报出没有定义这个方法的错误)。

作用:用来构建和初始化该类的对象。

调用时间:在实例化该类的时候被调用(即创建对象/new出一个实例的时候),一般在静态块,非静态块之后调用。

是否必须写:不一定非要写,有需要的时候才写,如果不写系统会默认的加一个隐式的无参构造方法,在实例化该对象的时候被调用。

无参vs 有参:无参构造方法不写的时候系统默认加的叫隐式构造方法,自己写出来是显示无参构造方法。有参的必须是要写出来的,有参构造函数根据参数类型、个数的不同可以写多个。

调用无参构造器构建的对象只有该类的属性,比如构建一个“Person” 这个对象,只能说这个对象有 eyes mouth age 等属性,调用有参构造器构建的对象,可以在构建对象的时候对某些属性赋予特定的值,比如调用有参构造的对象,除了有以上属性外,还可以知道age具体是多大、eyes是单眼皮等属性的具体信息。


子类一定要调用父类的构造方法吗?

一定,我的理解是必须有了父亲才会有儿子,所以是儿子实例化,也必须先创建父亲,否则儿子没发诞生,而创建父亲必须调用父类的构造方法完成,所以一定要调用父类的构造方法。


任何子类构造方法第一行肯定是this();或者super();两个择一,不能同时都有。  
this();调用本类的其它构造方法。(传递相应参数调用相应的方法),注:假设调用了另一个构造方法,假设叫法1,因为那个构造方法要先调用父类的,所以这时候也是先调父类的法1,再调自己的法1,然后才执行自己的这个构造方法(不会再调父类的这个构造方法了,因为this和super只能出现一个)  
super();调用父类的构造方法。  

例:

public classFather

{

    public Father(){

        System.out.println("父亲的无参构造方法~~");

    }


    public Father(String name){

        System.out.println("父亲的有参构造方法~~");

    }


    public Father(String name,int age){

        System.out.println("父亲的有参构造方法~~");

    }

}


package gouZaoMethods;

public classSon extendsFather

{

    public Son(){

        System.out.println("儿子的无参构造方法~");

    }

    public Son(String name,int age){

        this();

        System.out.println("儿子的name~" + name + age);

        System.out.println("儿子的有参构造方法~");

    }

    public static void main(String[] args)

    {

        Sonson = newSon();

        System.out.println();

        Sonson1 = newSon("fhj",20);

    }

}

输出:

父亲的无参构造方法~~

儿子的无参构造方法~


父亲的无参构造方法~~

儿子的无参构造方法~

儿子的name~fhj20

儿子的有参构造方法~


构造方法不能说被继承,也不能说被覆盖,只能说被调用

因为覆盖是指子类与父类同、参数相同且返回类型相同的方法才行,很明显子类父类的构造方法名字肯定不同,所以不能说被覆盖;

不能说被继承,是因为构造器时为了创建一个对象而诞生的,如果能继承的话,那创建的对象都成父类对象了,那里还会创建子类对象?爸妈的构造器创建了我,爷爷奶奶的构造器创建了爸爸,如果能继承的话,那我可以和爸爸用相同的构造器,就乱套了。另外还有一点,如果可以继承,那子类的构造器名字参数和父类的是一样的,但父类子类的名称不一样,所以构造器的名字也不可能一样,所以不能说是被继承。


关于构造方法的调用顺序:

1、 子类会无条件的调用(这里不能说继承,因为构造方法不能被继承)父类的构造方法:

A、父类是隐式无参:子类也是隐式无参

public classFather{}

public classSon extendsFather

{

publicstaticvoidmain(String[] args)

{

     Son son= newSon();

}

}

输出:什么也没有


B、 父类是隐式无参:子类是显示无参

public classFather{}

public classSon extendsFather

{

public Son(){

        System.out.println("儿子的无参构造方法~");

    }

publicstaticvoidmain(String[] args)

{

     Son son= newSon();

}

}

输出:儿子的无参构造方法~


C、 父类是显示无参:儿子是隐式无参

public classFather{

    public Father(){

        System.out.println("父亲的无参构造方法~~");

    }

}


public classSon extendsFather

{

publicstaticvoidmain(String[] args)

{

     Son son= newSon();

}

}

输出:父亲的无参构造方法~~


D、父亲是显示无参:儿子是显示无参

public classFather{

    public Father(){

        System.out.println("父亲的无参构造方法~~");

    }

}


public classSon extendsFather

{

public Son(){

        System.out.println("儿子的无参构造方法~");

    }

publicstaticvoidmain(String[] args)

{

     Son son= newSon();

}

}

输出:父亲的无参构造方法~~

儿子的无参构造方法~


由以上四点可以看出:不管子类写了无参还是没写无参构造方法,子类都会调先用父类的无参构造方法,如果父类没写,那子类就调用父类默认的,父类写了无参,子类就调用显示的。


2、父类只有有参数构造函数,子类在构造方法中必须要显示调用父类的构造函数,否则编译出错

A、父类只有有参构造函数:子类无任何构造函数或只有显示无参构造函数,编译报错:Implicit(隐式) super constructorFather() is undefined for default constructor. Must define an explicit(显示) constructor

public class Father{

    public Father(String name){

        System.out.println("父亲的有参构造方法~~");

    }

}


public classSon extendsFather

{

    public Son(){

        System.out.println("儿子的无参构造方法~");

    }

publicstaticvoidmain(String[] args)

{

     Son son= newSon();

}

}

如果父类没有有参构造器,子类写不写构造器都无所谓,但若父类只有有参的,子类不写有参的,子类在继承的时候只会找到有参的构造器,但自己有没有有参构造函数,所以会报错


B、父类只有有参构造函数:子类也写了有参构造器,但没有显示调用,也会报A中的错误

public class Father{

public Father(String name){

        System.out.println("父亲的有参构造方法~~");

    }

}


public classSon extendsFather

{

    public Son(String name){

        System.out.println("儿子的无参构造方法~");

    }

publicstaticvoidmain(String[] args)

{

     Son son= newSon(“xxx”);

}

}

因为这样他还是只会去找父类中默认的无参构造器,但父类中没有定义,找不到当然要报错


C、父类只有有参构造函数:子类也写了有参构造器,参数必须和父类中的类型、个数都一样才行,且子类构造函数第一行必须用super(参数)。


2、  父类既有无参数构造函数,也有有参构造函数,子类可以不在构造方法中调用父类的构造函数,这时使用的是父类的无参数构造函数,显示调用了就会调用父类中的构造方法。

public class Father{

public Father(){

        System.out.println("父亲的无参构造方法~~");

}


public Father(String name){

        System.out.println("父亲的有参构造方法~~");

    }

}


public classSon extendsFather

{

    public Son(String name){

        super("fqx");

        System.out.println("儿子的无参构造方法~");

    }

publicstaticvoidmain(String[] args)

{

     Son son= newSon(“xxx”);

}

}

输出:父亲的有参构造方法~~

儿子的有参构造方法~

在这种情况下,显示调用父类中的任意一个构造函数都行,可以无参,可以有与本构造函数不同的参数的,只要在父类中能找到就行,但是,不能同时调多个,只能用一次super;


在属性中封装一个默认的构造函数有什么用呢?

这道题刚好也很好的解释了上面调用父类构造器时出现的种种现象。

写一个无参数的构造器是为了避免发生错误。如果你没有定义一个有参数的构造器,你写不写这个无参数的构造器都无所谓,java会自动的给你加一个无参数的构造器来用于初始化一些数据。

但是如果你写了有参数的构造器,java就不会再为你添加无参数的构造器了。这样一来对你这个类可能没有什么影响,但是如果这个类被其它子类继承,而这个子类又没有指定使用父类哪个构造函数,那么java会默认的使用父类无参数的构造函数,而父类却没有定义无参数的构造函数,所以会出现错误。所以建议在定义了有参数的构造函数的同时,要再定义一个无参数的构造器。总之,还是那句话,在父类找的是哪个就执行哪个,即使子类的无参构造器调用父类含参构造器也行。


2.方法覆盖:
          (1)子类覆盖父类的方法,必须有同样的参数返回类型,否则编译不能通过
          (2)子类覆盖父类的方法,在jdk1.5后,参数返回类可以是父类方法返回类的子类
         (3)子类覆盖父类方法,可以修改方法作用域修饰符,但只能把方法的作用域放大,而不能把public修改为private
          (4)子类方法能够访问父类的protected作用域成员,不能够访问默认的作用域成员
         (5)子类的静态方法不能隐藏同名的父类实例方法
         (6)java与C++一样,继承的方法具有多态性
         //以上6个结论已经过代码验证


3.成员覆盖:
         当子类覆盖父类的成员变量时,父类方法使用的是父类的成员变量,子类方法使用的是子类的成员变量
          这个听起来很容易理解的一回事,但是实际使用过程中很多人容易搞混:尤其是在多态的时候,调用一个被继承的方法,该方法访问是一个被覆盖的成员m,那么方法中到底是访问了父类的成员还是子类的成员m?结论是,若实际调用的是父类的方法,就使用了父类的该成员m,若实际调用的是子类的方法,就使用子类的成员m,记住一句,每个类使用成员都相当于在前面加了 一个this指针。

无参数构造方法的覆盖

  首先明确一点带参数的构造方法不会被继承,也不存在覆盖的问题,因此只有无参的构造方法才存在覆盖这个问题,但是由于构造方法必须与所在的类同名,而子类的名称和父类不同,因此构造方法名字也显然不同,所以这种覆盖和普通方法的覆盖相比,无论从形式上还是从执行方法上都有很大的区别。



回复
分享到:

使用道具 举报

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-12-27 22:10 , Processed in 0.089469 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表