您的位置:首页 > 其它

SCJP认证 1.5.2 (1) 非访问修饰符

2011-02-26 18:10 337 查看
修饰符:

1)final, abstract

2)transient、synchronized、native、strictfp

3)static

首先我们介绍用于方法的修饰符,接着介绍应用于示例变量的修饰符,最后介绍static应用于变量和方法时怎样工作。

final方法

final关键字能防止方法在子类中重写,它常常用于执行方法的API功能。例如,Thread类具有一个名为isAlive()的方法,他检查线程是否仍然为活动的。但是如果扩展Thread类,确实没有任何方法能够正确地实现该方法(一个原因是它使用本地代码) ,因此,设计者将其设计成final类。就像不能子类化String类一样(因为需要能够信任String对象的行为),我们也不能重写核心类库中的很多方法。“不能重写”这一限制提供了安全保障,但是仍然应该很小心地使用它。组织子类重写方法会失去面向对象的很多优点,包括多态实现的可扩展性。典型的final方法声明如下:

class SuperClass{
public final void showSample(){
System.out.println("One thing");
}
}


扩展SuperClass是合法的,因为该类本身没有标识为final。但是,不能像下面的代码那样试图重写final方法showSample():

class SubClass extends SuperClass {
public void showSample(){//Try to override the final superclass method
System.out.println("Another Thing.");
}
}


上面的代码将会发生编译错误。

final变元

方法的变元是方法声明中出现在两个圆括号之间的变量声明。带多个变元的点典型方法声明如下所示:

class MyClass {
public Record getRecord(int fileNumber, int recNumber){

}
}


方法的变元实质上与局部变量相同。在前面的例子中,变量fileNumber和recordNumber 都将遵守应用于局部变量的规则。这意味着它们也可以带修饰符final:

class MyClass {
public Record getRecord(int fileNumber, final int recordNumber){

}
}


在这个例子中,将变量recordNumber声明为final,这当然意味着不能在该方法中修改它。这时,“修改” 是指为该变量重新赋一个新值。换句话说,final变元必须保持与传递给方法是参数锁具有的值相同。

抽象方法

抽象方法是一个已经声明了(声明成abstract) 但没有实现的方法。换句话说,该方法没有包含任何功能代码。也就是,它没有方法体。当要求子类必须提供实现时,可以将方法标识为abstract。例如,如果编写一个具有goUpHill()方法的抽象类Car,你可能希望Car的每个子类都必须定义其自己的、专属于某种车辆类型的goUpHill()行为。

public abstract void showSample();


注意,抽象方法是以分好而不是波形括号结尾的。在没有显示声明为abstract的类中,哪怕只有一个抽象方法也是非法的!

请看下面的非法类:

public class IllegalClass{
public abstract void doIt(){}
}


但是,可以使抽象类不带抽象方法。下面的代码能够编译:

public abstract class LegalClass {
void goodMethod(){
//lots of real implementation code here
}
}


在上面的例子中,goodMethod()不是抽象方法。有3条不同的线索能让你判断出它不是抽象方法:

1. 该方法为标识abstract

2. 方法声明包含波形括号,而不是以分号结束。换句话说,方法具有方法体。

3. 方法提供了实际的实现代码。

任何扩展抽象类的都必须实现超累的所有抽象方法,除非子类也是抽象的。规则如下:

抽象类的第一个具体子类必须实现超类的所有抽象方法。

“具体” 只不意味着它是非抽象的。因此,如果有一个抽象类扩展另一个抽象类,则该抽象子类不需要为继承的抽象方法提供实现。但是,迟早有人要建立非抽象子类(也就是可以被实例化的类),该子类必须实现来自继承树的所有抽象方法。下面的例子演示了具有两个抽象类的具体类的继承树:

public abstract class Vehicle {
private String type;
public abstract void goUpHill();
public String getType(){
return type;
}
}


public abstract class Car extends Vehicle{
public abstract void goUpHill();
public void doCarThings(){
//special car code goes here
}
}


public class Mini extends Car {
public void goUpHill(){

}
}


那么,其中Mini类有多少个方法呢?3个。它同时继承getType()方法和doCarThings() 方法,因为他们是公共的和具体的(非抽象) 。但是,由于父类Vehicle中goUpHill()抽象的。并且在Car中永远不会被实现(因此他保持是抽象的),所以,这一意味着Mini类——作为Vehicle下面的第一个具体类——必须是想goUpHill()方法。换句话说,Mini类不能将责任(抽象方法实现)推卸给继承书中的下一个类。但是类Car可以这样做,因为和Vehicle一样,Car也是抽象的。

要注意那些部位超类的抽象方法实现的具体类。下面的代码将无法编译:

public abstract class A {
abstract void foo();
}

class B extends A {
void foo(int I){}
}


类B不能编译,因为它没有实现继承的抽象方法foo()。尽管类B中的foo(int I) 方法好像是超累抽象方法的一种实现,但它只是一个重载方法(标识符相同,但变元不同的方法),因此,它没有完成超类的抽象方法的要求。

一个方法永远、永远、永远不能同时标志为abstract和final,或者同时标识为abstract和private。

思考一下:抽象方法必须被实现(这是指意味着要被子类重写) ,而final方法和private方法永远本鞥被子类重写。

可以这样说,abstract和final修饰符实际上是对立的。private方法不能被子类看到,所以他们也不能被重写,因此不能将其标识为abstract。

最后,你需要了解abstract修饰符永远不能与static修饰符组合使用。本届稍后部分将介绍static方法,但是现在只要记住下面的内容是非法的即可:

abstract static void doStuff();


它将产生一个错误,你现在应该熟悉它了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: