Java学习日记(四)
四、面向对象编程(三)
1、类的继承
1、继承的特点
java通过extends关键字实现继承,实现继承的类叫做子类,被继承的类叫做父类。例如水果和苹果的关系,苹果继承了水果,苹果是水果的子类,则苹果是一种特殊的水果。
因为子类是一种特殊的父类,因此父类包含的范围总要比子类广。
Java里子类继承父类的语法格式如下:
修饰符 class SubClass extends SuperClass
{
//类定义部分
}
下面程序作为子类继承父类的示范代码
先定义一个水果类
public class Fruit
{
public double weight;
public void info()
{
System.out.println("我是一个水果!重“
+weight+"g");
}
}
接下来定义一个水果类的子类,程序如下:
5.8 继承与组合
继承是实现类复用的重要手段,但继承带来了一个最大的坏处:破坏封装。相比之下,组合也是实现类复用的重要方式,而采用组合方式来实现类复用则能提供更好的封装性。
子类扩展父类时,子类可以从父类继承得到成员变量和方法,如果访问权限允许,子类可以直接访问父类的成员变量和方法,相当于子类可以直接复用父类的成员变量和方法。
为了保证父类有良好的封装性,不会被子类随意改变,设计父类通常应该遵循如下规则。
➢ 尽量隐藏父类的内部数据。尽量把父类的所有成员变量都设置成private访问类型,不要让子类直接访问父类的成员变量。
➢ 不要让子类可以随意访问、修改父类的方法。父类中那些仅为辅助其他的工具方法,应该使用private访问控制符修饰,让子类无法访问该方法;如果父类中的方法需要被外部类调用,则必须以public修饰,但又不希望子类重写该方法,可以使用final修饰符(该修饰符后面会有更详细的介绍)来修饰该方法;如果希望父类的某个方法被子类重写,但不希望被其他类自由访问,则可以使用protected来修饰该方法。
➢ 尽量不要在父类构造器中调用将要被子类重写的方法。
如果想把某些类设置成最终类,即不能被当成父类,则可以使用final修饰这个类,例如JDK提供的java.lang.String类和java.lang.System类。除此之外,使用private修饰这个类的所有构造器,从而保证子类无法调用该类的构造器,也就无法继承该类。对于把所有的构造器都使用private修饰的父类而言,可另外提供一个静态方法,用于创建该类的实例。
如果需要复用一个类,除把这个类当成基类来继承之外,还可以把该类当成另一个类的组合成分,从而允许新类直接复用该类的public方法。
5.9 初始化块
一个类里可以有多个初始化块,相同类型的初始化块之间有顺序:前面定义的初始化块先执行,后面定义的初始化块后执行。
在 Java 语言中,当实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建象。
初始化一般遵循3个原则:
静态对象(变量)优先于非静态对象(变量)初始化,静态对象(变量)只初始化一次,而非静态对象(变量)可能会初始化多次;
父类优先于子类进行初始化;
按照成员变量的定义顺序进行初始化。 即使变量定义散布于方法定义之中,它们依然在任何方法(包括构造函数)被调用之前先初始化;
加载顺序
父类(静态变量、静态语句块)
子类(静态变量、静态语句块)
父类(实例变量、普通语句块)
父类(构造函数)
子类(实例变量、普通语句块)
子类(构造函数)