1:关于继承
为了保证父类的良好封装性,不会被子类随意改变,设计父类时通常隐藏父类的内部数据,把父类属性改为private
如果父类中可以被重写,但不希望被其他类*访问可用protected修饰;
2:什么时候派生子类?
简而言之就是 如果子类需要额外增加新的属性;或者有新的行为方式那么可以派生新类,注意如果是只通过在父类中增加一个新的属性值就可以解决的问题就不要派生了;
3:使用组合派生新的类
示例如下:本例不太合适只作为示例
一般而言,继承是对已有的类进行补充改造获取一个特殊的版本;组合则是将两个具有明确整体局部关系的事物,采用组合关系实现复用;
使用组合关系来实现复用需要创建对象例如上边实现Bird时的里边用到了Animal1这个类,此时使用组合并没有增大系统的开销,因为即便通过继承来实现,也需要隐式的创建一个父类对象;而在此例子中只不过通过显式手动创建一个嵌入类的对象(也就是Animal1)
4:初始化块和构造器
初始化块在构造器之执行;
使用小方法:如果要定义两个构造器,那么相同的部分可以拿出来放在初始化块中<<<<<<<<<--------
初始化块可以用static修饰成为静态初始化块;
有意思的例子值得分析:
class Root
{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root()
{
System.out.println("Root的无参数的构造器");
}
}
class Mid extends Root
{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid()
{
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg)
{
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:" + msg);
}
}
class Leaf extends Mid
{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf()
{
//通过super调用父类中有一个字符串参数的构造器
super("parameter one");
System.out.println("执行Leaf的构造器");
} } public class Test
{
public static void main(String[] args) {
new Leaf();
new Leaf(); }
}
output:
示例代码
Root的静态初始化块 **
Mid的静态初始化块 * 类的初始化 总是限制性最顶层的父类的静态初始化快依次向下执行
Leaf的静态初始化块 **
Root的普通初始化块 ***
Root的无参数的构造器 *
Mid的普通初始化块 **对象的初始化向执行初始化快部分然后执行构造器当然还是想从父类开始依次向下
Mid的无参数的构造器 *
Mid的带参数构造器,其参数值:parameter one *
Leaf的普通初始化块 ***
执行Leaf的构造器 ***
Root的普通初始化块 *
Root的无参数的构造器 *
Mid的普通初始化块 **同上因为已经类已经初始化化完毕了,就不用再进行初始化;
Mid的无参数的构造器 *
Mid的带参数构造器,其参数值:parameter one *
Leaf的普通初始化块 *
执行Leaf的构造器 ***