能不能把一些相同的内容定义到一个独立的类中,然后,让其他的类与这个独立的类产生一个关系,建立好这个关系之后呢,这些其他的类就具备了这个独立的类的功能。
为了实现这样的基数,java提供了一个技术手段给我们使用,也是一个思想:继承
语句格式:class 子类名 extends 父类名{...}
要实现一个继承关系至少需要2个类
class Fu{}
class Zi extends Fu{}
这里的Zi我们称之为子类,派生类,
这里的Fu我们称之为父类,超类,基类
继承的好处:
1、提高了代码的复用性 看一看父类
2、提高了代码的维护性 只需要修改父类的内容
3、让类与类之间产生了继承关系,为了后面多态做铺垫(要有继承才能有多态)
继承的坏处:
1、类的耦合性增强了。(内聚)
开发的原则:
低耦合,高内聚
耦合:类与类之间的关系
内聚:类自己本身可以完成的事情
继承与构造方法的关系:
1、要想初始化子类,必选先初始化父类
2、为什么?
因为子类会继承父类的数据,甚至可能会使用父类的数据
所以在子类初始化之前,一定会先完成父类的初始化
注意:
每个子类的构造方法的第一句话默认是super().
看个例题:
class Father8 { int age; Father8(){ System.out.println("这是父类的无参构造方法"); } Father8(String s) { System.out.println("这是父类带参数的构造方法" + s); } } class Son8 extends Father8 { Son8() { System.out.println("子类的无参构造方法"); } Son8(String s) { System.out.println("子类带参数的构造方法" + s); } } public class ExtendsDemo7 { public static void main(String[] args) { Son8 s1 = new Son8("张三"); } }
结果:这是父类的无参构造方法
子类带参数的构造方法张三
先给Son8初始化,但是 每个子类的构造方法的第一句话默认是super(),所以初始化之前会先让Father初始化,因此先打印这是父类的无参构造方法,父类初始化完毕之后,再回到子类进行初始化,输出 子类带参数的构造方法张三
当父类中没有无参构造方法的时候,怎么办呢?
1、使用super关键字带参数的形式访问父类的带参数构造方法
2、子类通过this关键字调用本类的其他构造方法
注意,本类其他构造方法也必须可以访问父类拥有的构造方法
使用this关键字间接的调用父类的构造方法
无论在哪里调用父类的构造方法,只要最后保证在子类构造方法内容执行之前完成了父类的初始化就可以了
3、super(..)或者this(..)必须出现在第一条语句上
2、否则就会出现父类的数据进行了多次初始化
(重点)每个类只能初始化一次
再来个例题:
class X { X() { System.out.println("X"); } Y y = new Y(); } class Y { Y() { System.out.println("Y"); } Y(String s){ System.out.println("S"); } } class Z extends X{ Y y = new Y("s"); Z(){ System.out.println("s"); } Z(String s ){ System.out.println("Z"); } } public class ExtendsTest2{ public static void main(String[] args) { Z z = new Z("s"); } }
结果: Y
X
S
Z
第一步,Z初始化,发现Z还有一个父类X,所以先初始化父类。构造方法完毕之前会将数据初始化完毕,所以先new再走构造方法。所以先初始化Y,第一个输出Y,第二个输出X,第三个初始化类Z里面的Y,输出S,最后输出Z。