一、多继承

在java中,为了数据安全,只允许单继承。不过有些时候我们又需要多继承,进一步拓展类的属性和行为。在java中有提供实现多继承的方式,这种是方式是间接的实现类似多重继承的效果。实现方式有两种----接口和内部类。

1、接口

在介绍接口的时候,说过子类只能继承一个父类,也就是只能单继承,但是子类可以实现多个接口。接口是没有任何具体实现的。具体的用法如下:



1 interface CanFight {
 2     void fight();
 3 }
 4  
 5 interface CanSwim {
 6     void swim();
 7 }
 8   
 9 interface CanFly {
10     void fly();
11 }
12  
13 public class ActionCharacter {
14     public void fight(){
15         
16     }
17 }
18  
19 public class Hero extends ActionCharacter implements CanFight,CanFly,CanSwim{
20  
21     public void fly() {
22     }
23  
24     public void swim() {
25     }
26  
27     /**
28      * 对于fight()方法,继承父类的,所以不需要显示声明
29      */
30 }



2、内部类

如果子类的父类是具体类或者是抽象类,由于单继承的限制,这时候只能通过内部类来实现多继承。如下:

首先定义两个父类



1 public class Father {
 2     public int height(){
 3         return 175;
 4     }
 5 }
 6  
 7 public class Mother {
 8     public int weight(){
 9         return 95;
10     }
11 }



如何定义一个子类,让这个子类具备两个父类的行为和属性呢?



1 public class Son {
 2     
 3     /**
 4      * 内部类继承Father类
 5      */
 6     class Fatherlike extends Father{
 7         public int height(){
 8             return super.height() + 5;
 9         }
10     }
11      /**
12      * 内部类继承Mother类
13      */
14     class Motherlike extends  Mother{
15         public int weight(){
16             return super.weight() + 20;
17         }
18     }
19     
20     public int getHieght(){
21         return new Fatherlike ().height();
22     }
23     
24     public int getWeight(){
25         return new Motherlike ().weight();
26     }
27 }



二、代码块

1.什么是代码块?

在java代码中,用大括号{}将多行代码封装在一起,形成一个独立的数据体,用于实现特殊的功能和初始化数据。

2.四种代码块

1)普通代码块

普通代码块是用的最多的,例如在方法名后面用{}括起来的代码段。



1 public class Demo5 {
2     public void test(){
3         System.out.println("Hi");
4     }
5     
6 }



2)构造代码块

在类中定义,没有任何修饰符,构造二字首先我们想到的是构造器,构造器是在生成对象的时候被调用,构造代码块和构造器一样是在生成对象的时候被调用。



1 public class Demo5 {
 2     {
 3         System.out.println("我是代码块");
 4     }
 5     Demo5(){
 6         System.out.println("hill");
 7     }
 8     {
 9         System.out.println("我是代码块2");
10     }
11     
12     public static void main(String[] args) {
13         Demo5 demo5 = new Demo5();
14     }
15 }



输出结果:



我是代码块
我是代码块2
hill



从结果,很容易知道构造代码块定义的顺序在构造器调用前先被执行。因此构造代码块常用于:初始化实例变量、初始化实例环境。

3)静态代码块

静态二字,首先想到的是static关键字,与构造代码块的区别仅仅多了static关键字。



1 public class Test {
2     static{
3         System.out.println("静态代码块");
4     }
5 }



静态代码块的主要目的是对静态属性进行初始化,静态代码块在类加载的时候被执行,且只执行一次。

4)同步代码块

同步代码块是被synchronized关键字修饰的,其作用是加锁,同一时间只能一个线程进入该代码块中,是一种安全机制。

3、总结

静态代码块,随着类的加载而被执行,且只执行一次,主要作用是进行相关资源的初始化。

构造代码块,当创建对象的时候就被调用一次,且优先于构造器的。主要用于初始化不同对象共性的初始化内容和初始化实例环境。

执行顺序上,静态代码块最先,其次是构造代码块,最后是构造器。