介绍 abstract、static 和 final

Java 中有很多修饰符。今天看到一篇文章,作者对这些修饰符做了一个总结,并画了张表(http://blog.csdn.net/cdsnmdl/archive/2009/02/26/3940417.aspx)。不过这张表不够详尽也不够准确,我想补充一些东西。

初学者死记这张表是没用的,主要是在写代码的过程中了解,多练多写才是正途。有了一定的经验之后再来总结一下,能够对这些修饰符之间的关系有更深刻的了解。

常用修饰符主要分四种:与继承有关的修饰符 abstract、static 和 final;与可见性有关的修饰符 public、protected、private 和缺省修饰符;与多线程有关的修饰符 synchronized 和 volatile;与序列化有关的修饰符 transient。除此之外,还有 native 这个用不到的修饰符。

在这些修饰符中,与继承有关的三个修饰符 abstract、static 和 final 关系是最复杂的。本文尝试介绍这三个修饰符,并理清它们之间的关系。

-- abstract --
abstract 专门用来修饰类和方法。当它修饰方法时,表示这个方法是“抽象的”,也就是说当前位置没有实现,只是作了一个定义。抽象方法在什么地方实现呢?在子类当中。不同的子类可以有不同的实现。当 abstract 修饰类时,表示这个类包含有抽象方法,因而是一个“抽象类”。因为抽象类可能包含没有实现的方法,所以不可以创建实例。综上所述,我们需要注意几点:

1、如果一个类包含了抽象方法,这个类也必须用 abstract 来修饰;但一个 abstract 类不一定非要包含抽象方法。
2、抽象方法必须要通过子类来实现,所以它不可以是静态的,也不可以是 final 的。你可以在看完 final 的介绍之后再来看看这句话。
3、同上原理,抽象类也不可以是 final 的。


-- static --
static (静态的)专门用来修饰成员、方法和内部类。当它修饰方法时,表示这个方法的运行不需要依赖于类的实例;当它修饰成员时,表示这个成员独立于类的任何一个实例之外;当它修饰内部类时,表示这个内部类的实例化不需要依赖于其外部类的实例(反之,如果一个内部类没有 static 修饰符,就表示它的对象必须在其外部类的实例中才能创建。这样好理解些)。综上所述,我们需要注意几点:

1、非静态的内部类不能包含静态的方法和成员。
2、静态的内部类可以用 final 或 abstract 修饰,但两者不可以同时用。你可以在看完 final 的介绍之后再来看看这句话。
3、静态方法不会被继承,所以不可以是抽象的。


-- final --
final 可以修饰类、方法、成员和变量。当它修饰类时,表示这个类不可以有子类。典型的例子就是 String。为什么不可以有子类呢?因为子类可以覆写父类的行为,一个类加上 final 就说明它的行为是定死了的,不允许改变。当 final 修饰方法时,也是同样的道理,不允许子类覆写这个方法。当 final 修饰成员和变量时,表示它们必须且仅能赋值一次。一旦将对象赋给某个 final 成员或变量,那么这个成员或变量就不能再指向别的对象。综上所述,我们需要注意几点:

1、如果一个类已经是 final,再给里面的方法加上 final 是没有意义的。
2、final 和 static 同时用来修饰方法的话,因为 static 不存在继承,所以这时候 final 是多余的。
3、final 和 static 可以同时修饰成员,这是有意义的:表示该成员不依赖于类的实例,且只能赋值一次。
4、final 和 static 可以同时修饰内部类,这是有意义的:表示该内部类不依赖于其外部类的实例,而且不可以有子类。
5、抽象意味着必须要有继承,所以 abstract 和 final 任何时候都不可以同时使用。

 

 

此外,构造方法 (constructor) 是一种特殊的方法,它仅在构造对象时调用,也不可以被继承。所以 static、final 和 abstract 都不可以用来修饰构造方法。

 

 

以上就是对这三个修饰符的总结。若有遗漏错误之处,还请不吝赐教。有些地方如果你看不懂,没关系,多写自然就会懂了。

你可能感兴趣的:(介绍 abstract、static 和 final)