傻傻分不清楚super与this

当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,可以使用Java中的关键字super来访问父类中的成员(成员变量,成员方法,构造方法),需要注意的是,使用super调用的父类中的成员不能用private修饰(因为private限定只能在该类内使用)。




运行结果:

从运行结果可以看出,当创建子类对象时,会先加载父类的无参的构造器,其实,如果在父类中有静态代码块、初始化代码块、无参构造器的情况下,会先加载父类的静态代码块,其次加载初始化代码块,最后加载无参构造器。还有一种情况是子类中也存在静态代码块、初始化代码块、无参构造器,这时创建子类对象,将先加载父类的静态代码块,再加载子类的静态代码块,然后加载父类的初始化代码块,其次加载父类的无参构造器,最后分别加载子类的初始化代码块和子类的无参构造器。



运行结果:

这是因为静态代码块是属于类的,初始化代码块和构造方法属于对象,创建对象时先有类才能有对象,当类被加载时,静态代码块会先执行,由于类只加载一次,因此静态代码块只执行一次。
需要注意的是,static方法属于类所有,如果子类中定义了相同签名的static成员,则该成员属于子类所有,而非重新定义,static方法也没有多态,因为对象不会个别拥有static成员。
通过super关键字可以成功访问父类的成员变量和成员方法,但是如果把Man类中的第8行代码中的super改成this,结果将会变成打印的是Man类中的name属性的值。




  这是因为子类继承父类,父类中的属性不可以被重写,即使属性类型及属性的签名相同,使用this指的是当前类或当前对象,根据就近原则,访问的将不再是父类中的name属性。如果将子类第5行代码去掉之后,代码中的this调用的将是父类的name属性。
有个有意思的情况是,如果Chinese类继承于Man类,Man类又继承于Human类,三个类中都定义了公开的move()方法,如果在Chinese类的方法中调用super.move()方法,首先找的是直接父类(也就是Man类)中的move()方法,如果直接父类中没有,则继续找间接父类(也就是Human类)中的move()方法。
在子类的构造法中通过super或this调用父类的构造方法时,this()与super()只能选择其中一个调用,而且一定要在构造方法的第一行执行,并且只能出现一次。如果父类中定义了带参的构造方法,而没有手动添加无参的构造方法,这时继承该类的子类将报错,这是因为子类的无参构造方法会默认调用父类的无参构造方法,但父类中JVM添加的隐式的无参构造方法被带参的构造方法覆盖了,而且又没有手动添加一个无参的构造方法,这时子类就会因为找不到父类中的无参构造方法而出现错误,除非在子类的无参构造方法中用super关键字指定调用父类中的带参构造方法。
子类在实例化时默认调用了父类无参的构造方法,在定义一个类时,如果没有特殊需求,尽量在类中定义一个无参的构造方法,即使内容为空也无所谓,这是为了日后使用上的弹性,也避免被继承时出现错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值