编程思想阅读心得
1.对象入门
- 建立模型——“知识结构”。
- 不必强行记住运算符优先级,拿不准时加括号即可。
- 对象,一切都是对象。控制程序流程、初始化和清除、隐藏实现过程、类再生、多形性、对象的容纳、违例差错控制、Java IO系统、运行期类型鉴定、传递和返回对象、创建窗口和程序片、多线程、网络编程、设计方范式。
- 多线程,独立运行的片段叫作“线程”,利用它编程的概念就叫作“多线程处理”。
- C++和Java都是杂合语言,多重编程风格。
2.一切都是对象
- 程序运行时,最好对数据保存到什么地方做到心中有数。特别要注意的是内存的分配六种保存数据位置:
1)寄存器,最快的保存区域,处理器内部;没有直接的控制权,由编译器分配。也不可能在自己的程序里找到寄存器存在的任何踪迹。
2)堆栈,驻留于常规RAM(随机访问存储器)区域,尽管有些Java数据要保存在堆栈里——特别是对象句柄,但Java对象并不放到其中。
3)堆。一种常规用途的内存池,保存了Java对象。和堆栈不同,“内存堆”或“堆”(Heap)最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。RAM。
(4)静态存储。“静态”(Static)是指“位于固定位置”。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。 RAM“固定位置”。
(5)常数存储。常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数需要严格地保护,所以可考虑将它们置入只读存储器(ROM)。
(6)非RAM存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给 另一台机器。而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍可保持自己的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复成普通的、基于RAM的对象。
特例:对于基本数据类型,由于用new创建对象(特别是小的、简单的变量)并不是非常有效,因为new将对象置于“堆”里。对于这些类型,Java采纳了与C和C++相同的方法。也就是说,不是用new创建变量,而是创建一个并非句柄的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,能够更高效地存取。
Java所有数组均为Object对象,存储于堆内存中 - 软件库名为域名反转(BruceEckel.com -> com.bruceeckel.utility.foibles)软件包都以小写字母为标准。
- 对象作用域,Java对象不具备与主类型(基本数据类型)一样的存在时间。用new关键字创建一个Java对象的时候,它会超出作用域的范围之外。所以假若使用下面这段代码:
String s="a string"
//句柄s会在作用域的终点处消失。然而,s指向的String对象依然占据着内存空间,指向它的唯一一个句柄已超出了作用域的边界。垃圾回收器 - Java可以嵌入html注释文档
3.控制程序流程
- 自增和自减:对于前递增和前递减(如++A或–A),会先执行运算(指执行++运算),再生成值。而对于后递增和后递减(如A++或A–),会先生成值,再执行运算。
- 按位运算符:AND(&)运算符、OR(|)运算符、XOR(^异或)运算符、NOT(~非)运算符(一元运算符),重点是异或^运算符,不要当成了次方运算符。
- 位移运算符:<<左移运算符、>>右移运算符.
- 造型运运算符,cast运算符,强转
- Java不需要sizeof()运算符来满足这方面的需要,因为所有数据类型在所有机器的大小都是相同的(Java采用Unicode编码,一个字节能够存储一个汉字)。我们不必考虑移植问题——Java本身就是一种“与平台无关”的语言。
- 运算符计算顺序:
“溃疡患者特别喜欢(维生素)C”
Ulcer (溃疡) Unary:一元 + - + + - [[ 其余的 ]]
Addicts (患者) Arithmetic(shift);算术(和移位) / % + - << >>
Really (特别) Relational:关系 > < >= <= == !=
Like (喜欢) Logical(bitwise):逻辑(和按位) && || & | ^
C Conditional(ternary):条件(三元) A>B ? X:Y
A Lot Assignment:赋值 = (以及复合赋值,如=) - Java不支持goto语句
- 程序控制关键字
if-else
、return
、while
、do-while
、for
、switch case
中断break
continue
- Java方法重载:
override
区别过载方法:每个过载的方法都必须采取独一无二的自变量类型列表(参数列表),参数类型中,即使自变量的顺序也足够我们区分两个方法 - static方法不能访问非static方法,反之可以
4.初始化和清除
- JVM垃圾回收
System.gc()
- 静态数据初始化顺序:Java初始化顺序
在new B一个实例时首先要进行类的装载(类只有在使用New调用创建的时候才会被java类装载器装入)
1.在装载类时,先装载父类A,再装载子类B
2.装载父类A后,完成静态动作(包括静态块、静态变量,它们的级别是相同的,按代码中出现的顺序初始化)
3.装载子类B后,完成静态动作
类装载完成,开始进行实例化
1.在实例化子类B时,先要实例化父类A
2.实例化父类A时,先成员实例化(非静态代码)
3.父类A的构造方法
4.子类B的成员实例化(非静态代码)
5.子类B的构造方法
总结:先初始化父类的静态代码—>初始化子类的静态代码–>初始化父类的非静态代码—>初始化父类构造函数—>初始化子类非静态代码—>初始化子类构造函数 - 数组初始化,多维数组的初始化
5.隐藏实施过程
- 关键字
public
、protected
、private
.private
不能被继承,同一个包里继承类能够访问protected
成员,不同包里不能访问。public
成员放在类最上面提高代码可读性6.类再生
- 继承和组合(合成)要合理使用:考虑是否需要从新类上溯造型回基础类。若必须上溯,就需要继承。但如果不需要上溯造型,就应提醒自己防止继承的滥用。只要记住经常问自己“我真的需要上溯造型吗”,对于合成还是继承的选择就不应该是个太大的问题。
7.多形性
- 面向对象的程序设计语言(OOP)的三种最基本的特征:数据抽象、继承和多形性。
- 后期绑定,
Shape shape = new Circle();
Shape的draw()
方法会被覆盖,实际调用的是Circle的Draw()
方法。后期绑定介入。 - 内部类,内部类访问和对象生成
BaseClass instance = new BaseClass();
BaseClass.InnerClass a = instance.getInnerClass();//getInnerCase为返回内部类方法
内部类可以非常方便的隐藏实施细节(private内部类的合理使用和上溯造型)
Inner类除了InnerClassDemo类以外其他任何东西都不能访问。interface base{ void prints(); } public class InnerClassDemo { private class Inner implements Base{ public void prints(){ System.out.print("rtss"); } } public Inner getInstance(){ return new Inner(); } public static void main(String[] args){ InnerClassDemo s = new InnerClassDemo(); InnerClassDemo.inner = s.getInstance();//compile error Base dd = s.getInstance(); dd.prints(); } }
- 如果已经设计了某个特殊的清除进程,要求它必须作为垃圾收集的一部分进行覆盖衍生类的 finalize()时,务必记住调用 finalize()的基础类版本
8.面向对象特性和设计原则
- 面向对象三大特性:封装,继承,多态
- 单一职责原则SRP:指一个类的功能要单一,不能包罗万象。
- 里氏替换原则LSP:父类对象出现的地方都可以替换成子类对象(OO基本思想)。
- 依赖倒置原则DIP:具体依赖抽象,上层依赖下层。
- 接口隔离原则ISP:模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来。
- 开放封闭原则OCP:一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。