继承是Java面向对象的三大特征之一,是比较重要的一部分,与后面的多态有着直接的关系。继承就是子类继承父类的特征和行为,使得子类对象(实例)具备父类的实例域和方法,或子类从父类继承方法,使得子类具备父类相同的行为。java
①、Java继承的特色:this
②、继承的好处:spa
③、类的继承格式:code
在Java中经过 extends 关键字来实现继承关系,形式以下:对象
class 父类 { 属性、方法 } class 子类 extends 父类 { 属性、方法 }
提到Java的继承,确定离不开this,super关键字和构造器的使用,下面来介绍一下:blog
this关键字:表示引用当前对象或正在建立的对象。可用于调用本类的属性、方法、构造器。继承
public class Test { public static void main(String[] args) { Father father=new Father("tang_hao",20); father.show(); } } class Father{ String name; int age; public Father() { } public Father(String name) { //调用本类的无参构造器 this(); this.name = name; } public Father(String name, int age) { //调用本类的有参构造器 this(name); this.age = age; } public void show(){ System.out.println("name"+this.name+",age"+this.age); } }
super关键字:表示引用当前对象的父类。可用于调用父类的属性、方法、构造器。编译器
public class Test { public static void main(String[] args) { Son son=new Son(); son.show(); } } class Father{ String name="Father"; int age=40; public Father() { System.out.println("调用了父类的无参构造器"); } public void show(){ System.out.println("父类的Show方法"); } } class Son extends Father{ String name="Son"; int age=20; public Son() { //调用父类构造器 super(); } public void show(){ System.out.println("子类的Show方法"); System.out.println("本类属性:"+this.name+","+this.age); //调用父类方法 super.show(); System.out.println("父类属性:"+super.name+","+super.age); } }
注意:在使用this、super调用构造器的时候,this、super语句必须放在构造方法的第一行,不然编译会报错。不能在子类中使用父类构造方法名来调用父类构造方法。 父类的构造方法不被子类继承。调用父类的构造方法的惟一途径是使用 super 关键字,若是子类中没显式调用,则编译器自动将 super();也就是说会一直调到Object类,由于Object是全部类的父类。静态方法中不能使用 super 关键字。编译
前面讲到子类能够继承父类的非private修饰的属性和方法,那么咱们思考一下?父类的构造器可以被子类继承吗?答案是:不能!对于构造器而言,它只可以被调用,而不能被继承。 调用父类的构造方法咱们使用super()便可。class
咱们先来看一个示例:
public class Father { protected String name;//姓名 protected int age;//年龄 public Father(){ System.out.println("Father constructor"); } public void eat(){ System.out.println("Father eat..."); } public void sleep(){ System.out.println("Father sleep..."); } } class Son extends Father{ protected String name;//姓名 protected int age;//年龄 public Son() { System.out.println("Son constructor"); } public void eat() { System.out.println("Son eat..."); } public void sleep() { System.out.println("Son sleep..."); } public static void main(String[] args) { Son son=new Son(); son.eat(); son.sleep(); } }
运行结果:
从运行的结果来看,咱们只new了Son的实例,可是却调用父类的无参构造器,并且先输出了父类构造器的语句。这是由于:若是子类中没显式调用父类构造器,则编译器会自动在构造器方法第一行加上super()。
经过这个示例能够看出,构建过程是从父类“向外”扩散的,也就是从父类开始向子类一级一级地完成构建。并且咱们并无显示的引用父类的构造器,这就是java的聪明之处:编译器会默认给子类调用父类的构造器。
可是,这个默认调用父类的构造器是有前提的:父类有默认构造器。若是父类没有默认构造器,咱们就要必须显示的使用super()来调用父类构造器,不然编译器会报错:没法找到符合父类形式的构造器。
public class Father { protected String name;//姓名 protected int age;//年龄 public Father(String name, int age) { this.name = name; this.age = age; } public void eat(){ System.out.println("Father eat..."); } public void sleep(){ System.out.println("Father sleep..."); } } class Son extends Father{ protected String name;//姓名 protected int age;//年龄 public Son(String name, int age) { //这里父类没有默认构造器,因此必须显式的使用super() super("tang_hao",22); this.name = name; this.age = age; } public void eat() { System.out.println("Son eat..."); } public void sleep() { System.out.println("Son sleep..."); } public static void main(String[] args) { Son son=new Son("tang_hao",20); son.eat(); son.sleep(); } }
小结:子类会默认使用super()调用父类默认构造器,若是父类没有默认构造器,则子类必须显式的使用super()来调用父类构造器,并且super()必需要放在子类构造方法的第一行。
因此能不使用继承关系就尽可能不要使用继承。