Java编程思想 (2)
访问权限控制
访问权限控制:
- Java提供了访问权限控制修饰词控制访问权限。
- 权限从大到小依次为public,protected,包访问权限(没有关键词),private。
包:库单元
- 包内含有一组类,它们在单一的名字空间之下被组织在一起。
- 编写一个Java源代码文件时,此文件通常被成为编译单元。
- 每个编译单元内可以有一个public类,该类名称必须与文件名相同。
- 如果该编译单元还有额外的类,则包之外是无法看到的,这些类主要用于为主public类提供支持。
代码组织:
- Java可运行程序是一组可以打包并压缩为一个Java文档文件(JAR文件)的.class文件。
- 解释器负责这些文件的查找、装载和解释。
- 类库实际上是一组类文件。其中每个文件都有一个public类以及任意数量的非public类。
- 如果希望这些构件从属于同一个群组,可以使用关键字package。
- 如果使用package语句,它必须是文件中除注释以外的第一句程序代码。
Java解释器运行过程:
- 首先找出环境变量CLASSPATH,用作查找.class文件的根目录。
- 从根目录开始,解释器获取包名称并将每个据点替换成反斜杠。
- 从而从CLASSPATH根目录产生一个路径名称。
- 解释器就在这些目录中查找与你所要使用的类名称相关的.class文件。
Java没有条件编译:
- Java没有C的条件编译功能。
- C在绝大多数情况下使用条件编译解决跨平台问题。
- 但该问题在Java中不存在,因而条件编译是不必要的。
包访问权限:
- 如果不提供任何访问权限修饰词,则意味着当前类的权限为“包访问权限”
- 经由包访问权限,处于同一个编译单元中的所有类之间都是自动可访问的。
- 当把类组织起来放进一个包内时,也就给它们的包访问权限的成员赋予了相互访问的权限。
public权限:
- 使用public关键字,也称作接口访问权限。
- public关键字之后紧跟的成员对每个类都是可用的。
Example07. Default Package
默认包:
- 处于相同目录并且没有给自己设定任何包名称。
- Java将这样的文件自动看作是隶属于该目录的默认包中。
private权限:
- 使用private关键字。
- 除了包含该成员的类以外,其他任何类都无法访问这个成员。
protected权限:
- 使用private关键字,也称作继承访问权限。
- 基类可以通过protected关键字将对成员的访问权限赋予其派生类。
- protected也提供包访问权限,相同包内的其他类可以访问protected元素。
类的访问权限:
- Java中反问权限修饰词可用于确定库中哪些类对于该库的使用者是可用的。
- 如果希望某个类可以为某个客户端程序员使用,就可通过把关键字public作用于整个类定义来实现。
类访问权限的一些规定:
- 每个编译单元(文件)只能有一个public类。
- public类的名称必须完全与含有该编译单元的文件名相匹配。
- 编译单元完全不带public类也是可行的。这种情况下文件可以随意命名。
- 类不可以是private的也不可以是protected的。
- 对于类的访问权限只有两个选择:包访问权限或public。
关于单例:
- 如果不希望其他任何人对该类拥有访问权限,可以把所有的构造器都指定为private,从而阻止任何人创建该类的对象。
- 但有一个例外,就是可以在该类的static成员内部创建。
Example08. Singleton
<-- 注意:
- 如果没能为类访问权限指定一个访问修饰符,它就会默认得到包访问权限。
- 这就意味着该类的对象可以由包内任何其他类来创建,但在包外是行不通的。
复用类
toString方法:
- 每个非基本类型的对象都有一个特殊的方法,toString()。
- 当编译器需要一个String而当前只有一个类的对象时,该类的toString方法便会被调用。
- 每当想要使所创建的类具有像字符串一样的行为时,仅需编写toString()方法即可。
继承语法:
- 使用关键字extends,派生类会自动得到基类中所有的域和方法。
- 即使是一个程序中含有多个有main方法的类,也只有命令行调用的那个类的main()方法会被调用。
- 为了继承,一般的规则是将所有的数据成员都指定为private,将所有方法指定为public。
- Java用super关键字表示超类。当前类就是超类继承来的。
基类初始化:
- Java会自动在导出类的构造器中插入对基类构造器的调用。
- 如果没有默认的基类构造器,或调用一个带参数的基类构造器,必须用关键字super显示编写调用基类构造器的语句。
Java不会名称屏蔽:
- 如果基类拥有某个已经被多次重载的方法名称。
- 那么在导出类中重新定义该方法名称并不会屏蔽其在基类中的任何版本。
- 因此无论在该层或它的基类中对方法进行定义,重载机制都可以正常工作。
向上转型:
- 由导出类转型成基类,一般称为向上转型。
- 是从一个较专用类型向较通用类型的转换,总是很安全的。
- 编译器在未指定特殊标记的情况下,依然允许向上转型。
final关键字:
- 根据上下文环境,final的含义存在细微区别,通常指的是“这是无法改变的”。
- 修饰数据时,表示编译器常量,这类常量定义时必须对其赋值。
- 一个既是static又是final的域只能占据一段不能改变的存储空间。
- 对于基本类型,final使数值恒定不变。
- 对于对象引用,final使引用恒定不变。一旦初始化指向一个对象,就不能改指向另一个对象,但对象自身可以被修改。
- 修饰参数时,这意味着无法在方法中更改参数引用指向的对象。
- 修饰方法时,使用final方法将防止任何继承类修改它的含义,确保继承使方法行为不变,不会被覆盖。
- 修饰类时,表明该类不能被继承。
<-- 注意:类中所有private方法都隐式指定为final的。由于无法取用private方法,也就无法覆盖它。
类的初始化和加载:
- 类的代码在初次使用时才加载。
- 这通常指加载发生于创建类的第一个对象时。
- 访问static域或static方法时也会发声加载。
类加载后对象初始化过程:
- 首先对象中所有基本类型都设为默认值,对象引用设为null。通过将对象内存设为二进制0值完成
- 然后调用基类构造器。若基类自身还有基类,则第二个基类构造器会被调用,依此类推。
- 基类构造器和导出类构造器一样,以相同顺序经历相同过程。
- 基类构造器完成之后,实例变量按其次序被初始化。
- 最后,构造器其余部分被执行。
Example09. Extends and Initialization
多态
方法调用绑定:
- 将一个方法调用同一个方法主体关联起来被称作绑定。
- 若在程序执行前进行绑定,称作前期绑定。
- 在运行时根据对象的类型进行绑定,成为后期绑定,也叫动态绑定或运行时绑定。
动态绑定:
- 实现方法是在对象中安置某种"类型信息"。
- Java中除了static方法和final方法(包括private方法)外,其他所有方法都是后期绑定。
Example10. Polymorphism
Java多态机制的缺陷:
- private方法被自动认为是final方法且对导出类屏蔽,因此不会被覆盖。
- 如果直接访问某个域,这个访问就将在静态编译期间进行解析.
- 如果某个方法是静态的,它的行为就不具有多态性。
Example11. Defect of Polymorphism (1)
Example12. Defect of Polymorphism (2)
一个复杂对象的构造器调用要遵照下面的顺序:
- 分配给对象的存储空间初始化为二进制0值
- 调用基类构造器,这个步骤会不断反复递归下去,首先是构造这种层次的根,然后是下一层导出类,直到最底层的导出类。
- 按声明顺序调用成员的初始化方法。
- 调用导出类的构造器主体。
注意:构造器中唯一能够安全调用的那些方法是基类中的final方法,因为它们不会被覆盖。
Example13. Polymorphism of constructor
协变返回类型:
- Java SE5增加了协变返回类型。
- 它表示导出类中的被覆盖方法可以返回基类方法的返回类型的某种导出类型。
- 即协变返回类型允许返回比被覆盖基类方法的返回类型更具体的类型。
Example14. Covariant
向下转型:
- C++中,我们必须执行一个特殊的操作来获得安全的向下转型。
- 在Java中,所有转型都会得到检查。
- 即使只是一次普通的加括弧形式的类型转换,进入运行期时仍然会对其进行检查。
- 如果运行是检查该类不是期望的类型,就会返回一个ClassCastException,即类转型异常。
- 这种运行期间对类型进行检查的行为称作“运行时类型识别”(RTTI)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。