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方法声明如下:
扩展SuperClass是合法的,因为该类本身没有标识为final。但是,不能像下面的代码那样试图重写final方法showSample():
上面的代码将会发生编译错误。
final变元
方法的变元是方法声明中出现在两个圆括号之间的变量声明。带多个变元的点典型方法声明如下所示:
方法的变元实质上与局部变量相同。在前面的例子中,变量fileNumber和recordNumber 都将遵守应用于局部变量的规则。这意味着它们也可以带修饰符final:
在这个例子中,将变量recordNumber声明为final,这当然意味着不能在该方法中修改它。这时,“修改” 是指为该变量重新赋一个新值。换句话说,final变元必须保持与传递给方法是参数锁具有的值相同。
抽象方法
抽象方法是一个已经声明了(声明成abstract) 但没有实现的方法。换句话说,该方法没有包含任何功能代码。也就是,它没有方法体。当要求子类必须提供实现时,可以将方法标识为abstract。例如,如果编写一个具有goUpHill()方法的抽象类Car,你可能希望Car的每个子类都必须定义其自己的、专属于某种车辆类型的goUpHill()行为。
注意,抽象方法是以分好而不是波形括号结尾的。在没有显示声明为abstract的类中,哪怕只有一个抽象方法也是非法的!
请看下面的非法类:
但是,可以使抽象类不带抽象方法。下面的代码能够编译:
在上面的例子中,goodMethod()不是抽象方法。有3条不同的线索能让你判断出它不是抽象方法:
1. 该方法为标识abstract
2. 方法声明包含波形括号,而不是以分号结束。换句话说,方法具有方法体。
3. 方法提供了实际的实现代码。
任何扩展抽象类的都必须实现超累的所有抽象方法,除非子类也是抽象的。规则如下:
抽象类的第一个具体子类必须实现超类的所有抽象方法。
“具体” 只不意味着它是非抽象的。因此,如果有一个抽象类扩展另一个抽象类,则该抽象子类不需要为继承的抽象方法提供实现。但是,迟早有人要建立非抽象子类(也就是可以被实例化的类),该子类必须实现来自继承树的所有抽象方法。下面的例子演示了具有两个抽象类的具体类的继承树:
那么,其中Mini类有多少个方法呢?3个。它同时继承getType()方法和doCarThings() 方法,因为他们是公共的和具体的(非抽象) 。但是,由于父类Vehicle中goUpHill()抽象的。并且在Car中永远不会被实现(因此他保持是抽象的),所以,这一意味着Mini类——作为Vehicle下面的第一个具体类——必须是想goUpHill()方法。换句话说,Mini类不能将责任(抽象方法实现)推卸给继承书中的下一个类。但是类Car可以这样做,因为和Vehicle一样,Car也是抽象的。
要注意那些部位超类的抽象方法实现的具体类。下面的代码将无法编译:
类B不能编译,因为它没有实现继承的抽象方法foo()。尽管类B中的foo(int I) 方法好像是超累抽象方法的一种实现,但它只是一个重载方法(标识符相同,但变元不同的方法),因此,它没有完成超类的抽象方法的要求。
一个方法永远、永远、永远不能同时标志为abstract和final,或者同时标识为abstract和private。
思考一下:抽象方法必须被实现(这是指意味着要被子类重写) ,而final方法和private方法永远本鞥被子类重写。
可以这样说,abstract和final修饰符实际上是对立的。private方法不能被子类看到,所以他们也不能被重写,因此不能将其标识为abstract。
最后,你需要了解abstract修饰符永远不能与static修饰符组合使用。本届稍后部分将介绍static方法,但是现在只要记住下面的内容是非法的即可:
它将产生一个错误,你现在应该熟悉它了
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();
它将产生一个错误,你现在应该熟悉它了
相关文章推荐
- SCJP认证 1.5.2 (2)非访问修饰符
- SCJP认证 1.7小结(声明访问控制)
- java中四种修饰符访问权限的区别及详解过程(一个链接)
- 19、vftpd基于PAM_MYSQL进行虚拟用户的认证且每个用户有自己的独立目录及不同的访问权限
- 访问需要HTTP Basic Authentication认证的资源的各种语言的实现
- java 访问修饰符
- 你所访问的站点在微博的认证失败 21322
- PHP面向对象——访问修饰符介绍
- C#类的访问性 类成员的访问修饰符
- SCJP认证套题解析卷2
- 访问需要HTTP Basic Authentication认证的资源的各种语言的实现
- RHEL4- WEB服务(十二)用户访问apache服务器认证
- postgresql访问认证设置
- Scala语言的访问修饰符
- 黑马程序员_学习笔记10——引用类型与值类型,继承,访问修饰符,里氏转换
- 访问修饰符权限
- JAVA访问权限修饰符用法总结
- 黑马程序员之访问修饰符及各种元素的访问修饰符的默认值
- C#中类的可访问修饰符
- 访问修饰符 自我理解