6.子类的构造方法
子类之所以要叫子类,因为它继承了父类。那我们知道类的构造方法是用来给类的成员变量进行初始化的,那么子类继承了父类,子类如何给继承下来的父类成员变量初识化呢?
注:实例化对象的时候,都会自动调用构造方法
super.成员变量名:表示访问父类的成员变量
super.成员方法名:表示访问父类的成员方法
super():表示访问父类的构造方法
父子父子有父才有子,所以子类实例化对象时,需要先调用父类的构造方法,然后在执行子类的构造方法,super() 就是用来访问父类的构造方法
当没有构造方法时编译器会自动生成:
当子类和父类都没有定义构造方法时,并不代表它们没有,在程序运行的时候,编译器会自动生成,且还会在自动生成的子类构造方法中的第一行生成 super()
子类构造方法中默认会调用父类的无参构造方法,但不会默认调用有参的构造方法:
class Animal { public String name; Animal() { name = "阿黄"; } public void eat() { System.out.println(name+"吃饭"); } } class Dog extends Animal { public String name; Dog() { //super(); name = "阿福"; } public void eat() { System.out.println(super.name+"吃狗粮"); } } public class Test { public static void main(String[] args) { Dog dog = new Dog(); dog.eat(); } }
如果父类的构造方法是无参的,那么在子类的构造方法中编译器会自动生成一个super,用户不需要自己写
如果父类的构造方法是有参的,但是子类的构造方法中并没有采用 super() 调用,编译器则会报错
如果父类的构造方法是有参的:
Animal(String name) { this.name = name; } 则用户需要自己在子类的构造方法需加 super() : Dog() { super("阿黄"); name = "阿福"; }
在构造子类对象时,先执行父类的构造方法,然后执行子类的构造方法。因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。
父子父子 肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整 ,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整
注:编译器只会在父类构造方法无参的情况下,才会自动生成一个 super 来调用父类的构造方法。当父类是有参的构造方法时,我们必须自己写一个 super 放在构造方法的第一行来调用父类的构造方法
注意:
若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用父类构造方法
如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
super(...)只能在子类构造方法中出现一次,并且不能和this同时出现
7.super和this
super 和 this 都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句
super 和 this 的相同点:
都是 Java 的关键字
只能在类的非静态的方法中使用,只能用来访问非静态的成员方法和成员变量
在构造方法中调用时,必须在构造方法的第一行,但是不能同时存在
super 和 this 的不同点:
this 是当前对象的引用,super 相当于子类对象中从父类继承下来的部分成员的引用
在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
在构造方法中:this(...)用于调用本类构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现
构造方法中一定会存在super(...)的调用,当父类构造方法无参时,用户没有写 super 编译器也会增加,但是this(...)用户不写则没有
8.protected访问限定符
为了实现封装特性,Java中引入了访问限定符 。那么我们今天就来学习 protected 访问限定符
protected:可以用在同一包中的同一类,同一包中的不同类,还可以用在不同包中的子类
前两种相信大家都会了,那我们今天就来将一下 protected 修饰的成员变量如何在不同包中的子类中使用。
protected 修饰的成员变量在不同包中的子类中使用:
package Demo1; public class Animal { protected String name = "阿黄"; protected int age = 1; protected void eat() { System.out.println(name+"吃饭"); } } import Demo1.Animal; class Dog extends Animal { public void fun() { System.out.println(name); eat(); } } public class Test { public static void main(String[] args) { Dog dog = new Dog(); dog.fun(); } }
运行结果:
上述代码也就体现了,protected 修饰的成员如何在不同包中的子类中使用
9.继承方式
在Java中只支持以下几种继承方式:
10.final关键字
final关键可以用来修饰变量、成员方法以及类
①修饰变量或字段,表示常量(即不能改变)
②修饰类:表示此类不能被继承
这样就可以在语法上进行限制继承
③修饰方法:表示该方法不能被重写