[Thinking in Java]Nothing but Java
1 对象(Double Elephants)
1.1 抽象
- 万物皆对象。什么东西都可以抽象成属性和方法,达到可重用的目的。
- 对象之间交流靠发送消息。就是通过调用某个特定对象的方法来达到消息传递的目的。
- 每个对象由其它对象组成。对象可重用,可以根据简单的对象构建更加复杂的对象。
- 每个对象都有对应的类型。即对象是某个类的实例,这个类便是类型,不同类型之间的区别是:不同的类可以发送和接收不同的消息。
- 特定类型的所有对象可以接收和发送同一类消息。继承相关。
1.2 每个对象都有一个接口
接口决定了实现该接口的类型的对象能发出什么消息。比如手机在初期就被设计成为可以[打电话]、[发短信]、[拍照],这些动作可以看做是接口,实现了这些接口就是一部手机。接口把这些必要的方法聚集起来,就能让实现接口的类型发出指定的消息。
1.3 每个对象都提供服务
将对象看作服务提供者,避免对象累赘,提高对象的内聚性,可重用性。
1.4 被隐藏的具体实现
访问控制:将程序开发人员分为类创建者和客户端程序猿,只向客户端程序猿暴露必要的部分,因为有些属性和方法在类内部操作是必要的,但是客户端程序猿并不需要关心,不让其访问和操作对象内部脆弱的地方,可以减少bug,提高安全性,也可以让他们看出哪些东西对他们来说是重要的。其次,访问控制让接口的实现和调用分离,即使内部发生了翻天覆地的变化,也不会影响客户端程序的使用。
public:任何人可使用;private:类型内部可使用,外部无法访问;protected:类型内部可使用,与private相似,但是继承的类可以直接访问protected;无访问指定词:包访问权限,在同一个包内,可以看做是public,但是在不同类中却可以看做是private,无法访问无访问指定词的属性和方法;
package com.chenlei.study.thinkinginjava;
/**
* @author chenlei
* @date 2016年4月18日 下午10:55:16
* @version 1.0
* @description
*/
public class AccessSpecifier {
String string = "default field from same package";
String print(){
return "default method from same package";
}
}
package com.chenlei.study.utils;
/**
* @author chenlei
* @date 2016年4月18日 下午10:56:47
* @version 1.0
* @description
*/
public class AccessSpecifierOtherPackage {
String string = "default field from another package";
String print(){
return "default method from another package";
}
}
package com.chenlei.study.thinkinginjava; import com.chenlei.study.utils.AccessSpecifierOtherPackage; /**
* @author chenlei
* @date 2016年4月18日 下午10:59:41
* @version 1.0
* @description 访问限定词
*/
public class AccessSpecifierEntry { public static void main(String[] args) {
String stringSamePackage = new AccessSpecifier().string;
new AccessSpecifier().print(); String stringOtherPackage = new AccessSpecifierOtherPackage().string;//The field AccessSpecifierOtherPackage.string is not visible
new AccessSpecifierOtherPackage().print();//The method print() from the type AccessSpecifierOtherPackage is not visible
}
}
1.5 复用
复用并不是一味地继承,这样可能导致过分复杂的设计,而是在合适的时候用不同的已有对象组合成一个新的对象。
1.6 继承
拥有基类所有的属性和方法,但是想要扩展或改写某些方法时,不必创建新对象,可以继承基类并进行方法覆盖或扩展。这就意味着继承自基类的子类在接收到父类能够接手的消息时,能够做出响应,如果不覆盖父类的方法,子类将会做出和父类一样的响应,否则做出自己特定响应。也就是说子类能够对发送给父类的所有消息作出相应。
当基类完全继承和覆盖父类方法并不添加其他属性和方法,也不实现其他接口时,可以说子类是一个基类完全的替代,子类就是一个基类类型;当子类不满足前面的条件时,子类和基类就不完全一样了,子类就不是一个纯粹的基类类型。
package com.chenlei.study.thinkinginjava;
/**
* @author chenlei
* @date 2016年4月18日 下午11:27:46
* @version 1.0
* @description 转型
*/
public class Cast {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle();
Circle circle = new Circle();
Shape shape = new Shape(); shape = circle;
circle.computeArea();
shape.computeArea(); Circle circle2 = (Circle) shape;//转换成功,因为shape指向circle的地址,是一个circle的实例 shape = new Shape();
circle = (Circle) shape;//com.chenlei.study.thinkinginjava.Shape cannot be cast to com.chenlei.study.thinkinginjava.Circle
circle.computeArea();
shape.computeArea(); shape = rectangle;
rectangle.computeArea();
shape.computeArea(); shape = new Shape();
rectangle = (Rectangle) shape;//com.chenlei.study.thinkinginjava.Shape cannot be cast to com.chenlei.study.thinkinginjava.Rectangle
rectangle.computeArea();
shape.computeArea();
}
} class Shape{
protected Double area = 1d;
public void computeArea(){
System.out.println("shape");
System.out.println(area);
};
} class Circle extends Shape{
@Override
public void computeArea(){
System.out.println("circle");
super.computeArea();
}
} class Rectangle extends Shape{
private Double width = 1d;
private Double height = 2d;
private Double perimeter; @Override
public void computeArea() {
System.out.println("rectangle");
area = width * height;
System.out.println(area);
} public void computePerimeter(){
System.out.println("rectangle");
perimeter = 2 * (width + height);
System.out.println(perimeter);
}
}
子类可以自动转化成一个父类,因为父类的所有消息,子类都可以响应;一个子类却不能强制转化为父类,因为子类有很多,无法具体到某一个特定的子类(除非父类引用的子类的一个实例)。很显然子类之间也无法相互强制转换,在编译期就会出错。所以向上转型是安全的,向下转型是不安全的,因为一个圆一定是一个形状,但是一个形状却不能具体到到底是一个圆还是一个三角形。
1.7 多态
- 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
- 当把一个子类看作一个父类类型时(泛化),调用这个泛化的父类类型的方法或接口,到底是调用的父类的方法呢还是调用子类的方法?(子类)
- 非面向对象的语言编译器,会将会将函数的调用在运行前绑定,运行时直接解析到具体地址;面向对象的语言在编译时并不能确定具体哪一个方法将被调用,而是用一小段代码通过在对象中存储的具体信息来计算方法体的地址,方法体的地址会直到运行时才能被确定。
- 下面这个例子因为多态,程序更加简洁易扩展,而且因为多态才让不同的对象通过同一个方法做了正确的事
package com.chenlei.study.thinkinginjava;
/**
* @author chenlei
* @date 2016年4月19日 下午10:45:56
* @version 1.0
* @description 多态
*/
public class Polymorphism { public static void main(String[] args) {
Bird bird = new Bird();
Chicken chicken = new Chicken();
Goose goose = new Goose(); move(bird);//----bird move----
move(chicken);//----chicken walk----
move(goose);//----goose fly----
} public static void move(Bird bird){
bird.move();
} } class Bird{
public void move(){
System.out.println("----bird move----");
}
} class Chicken extends Bird{
@Override
public void move() {
System.out.println("----chicken walk----");
}
}
class Goose extends Bird{
@Override
public void move() {
System.out.println("----goose fly----");
}
}
1.8 单根继承
所有对象最终都继承自Object类。单根继承保证所有对象都具备某些功能,比如Object的hashCode和equals方法等,这让一些更高级别的操作更加便利,比如GC和异常处理。
1.9 容器
1.Java里常用的容器,后面必须专门花时间总结,并且从源码角度分析与实现。
2.范型:在JSE5之前,容器里只能存储Object,这就使得从容器中取回对象时需要进行不安全的向下转型,JSE5引入范型(一对尖括号,中间是类型 List<String> list = new ArrayList<String>(); ),这就使得取回元素时就像放入时一样,不需要再转型。
1.10 对象的创建和生命周期
对象的存储位置可以是堆栈或堆。前者需要在程序编写时确定对象的存储空间、生命周期和类型,虽然在某种情况下这种控制方法很有效,但是却牺牲了灵活性,甚至因为程序未及时销毁对象导致内存泄漏;后者的创建和销毁是动态管理的,只有在程序运行需要的时候才能确定对象的存储空间、生命周期和类型,Java中采用的后者,创建对象时需要使用new关键字构建动态对象,Java专门的垃圾回收机制自动释放对象占用的内存,来避免暗藏的内存泄漏问题,可以不显式地在代码中调用方法释放内存,这些都是基于单根继承和对象在堆中管理这两个特性来实现的。
1.11 异常处理
我觉得异常处理主要有两点作用:一是捕获到异常后作出报告、捕获并对异常情况作特殊处理,避免程序终止;二是便于完善代码,使程序更加健壮。
1.12 并发编程
多线程、共享资源锁
1.13 Java与Internet
- C/S,环境、版本更新问题。
- B/S,只需要一个浏览器。
- 服务器返回静态页面:功能单一,交互困难不优雅。
- 服务器返回静态页面和客户端代码:插件,比如Applet、Flash等;脚本语言,如JavaScript、VBScript等。前者只要下载插件就能百分百运行程序,但是并不是所有浏览器都有各自的插件版本(针对Applet),所有浏览器都支持javascript,但是各个浏览器对其实现方式各有不同,调试起来一团糟。
- 服务器端编程:这才是Java发威的地方。
[Thinking in Java]Nothing but Java的更多相关文章
- java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出
上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...
- 【Java大系】Java快速教程
感谢原作者:Vamei 出处:http://www.cnblogs.com/vamei Java是面向对象语言.这门语言其实相当年轻,于1995年才出现,由Sun公司出品.James Gosling领 ...
- 《深入理解Java虚拟机》Java内存区域与内存溢出异常
注:“蓝色加粗字体”为书本原语 先来一张JVM运行时数据区域图,再接下来一一分析各区域功能: 程序计数器 程序计数器(program Counter Register)是一块较小的内存空间,它可以 ...
- Tomcat报java.lang.OutOfMemoryError: Java heap space错误停止运行如何解决
最近开发的一个商业项目,部署完成后,经常出现Tomcat挂掉的现象,报的异常是:java.lang.OutOfMemoryError: Java heap space,上网google了一下,了解了一 ...
- MyCAT报java.lang.OutOfMemoryError: Java heap space
早上同事反映,mycat又假死了,估计还是内存溢出,查看了一下错误日志. INFO | jvm | // :: | java.lang.OutOfMemoryError: Java heap spac ...
- 【Java】实战Java虚拟机之五“开启JIT编译”
今天开始实战Java虚拟机之五“开启JIT编译” 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实战Ja ...
- Java提高篇——Java 异常处理
异常的概念 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error:如果你用Syst ...
- Java import以及Java类的搜索路径
如果你希望使用Java包中的类,就必须先使用import语句导入.import语句与C语言中的 #include 有些类似,语法为: import package1[.package2-].cl ...
- [Java] SoapUI使用Java获取各时间日期方法
import java.util.*; import java.text.SimpleDateFormat; // current date String dateNew = today() // t ...
- Tomcat 启动项目报错 java.lang.OutOfMemoryError: Java heap space
近日使用myeclipse 部署web项目,启动tomcat时报错: SEVERE: Error waiting for multi-thread deployment of directories ...
随机推荐
- 使用命令行工具运行Xcode 7 UI Tests
原文:Run Xcode 7 UI Tests from the command line 苹果在Xcode 7中引入了一项新技术UI Tests,允许开发者使用Swift或Objective C代码 ...
- 一步一步搭框架(asp.netmvc+easyui+sqlserver)-01
一步一步搭框架(asp.netmvc+easyui+sqlserver)-01 要搭建的框架是企业级开发框架,适用用企业管理信息系统的开发,如:OA.HR等 1.框架名称:sampleFrame. 2 ...
- DOM扩展之 专有扩展
11.4.3 contains() 方法 用来确定某个节点是不是另一个节点的后代. 注:a.contains(a) 也是返回true.说明contains方法搜索是从自身开始的. DOM Level ...
- 数据导出到excel
jsp页面: 数据table: <form action="/export.jsp" method="post" id="expform&quo ...
- 如何在静态博客hexo中只显示摘要信息
默认情况下hexo博客(如本站)的首页显示的是完整的文章 – 而文章比较长的时候这无疑会带来诸多不遍. 那怎么样才能只显示个摘要呢? 方法说白了,其实很简单 – 只要加入一个<!-- more ...
- macbook air 128g 磁盘清理
使用 du 命令发现 ~/Library/Developer/Xcode/DerivedData 占用了大量空间,这些都是xcode对以前建过的project源码文件建立的索引等,如果不需要可以都删 ...
- 图表控件FlowChart.NET详细介绍及免费下载地址
FlowChart.NET是一款专业的.NET平台下的流程图及图表控件,它可以运行在任何C#, VB.NET或Delphi.NET语言编写的软件中.能够帮助你创建工作流程图.对象层次和关系图.网络拓扑 ...
- oracle全文索引
1.检查数据库是否具有全文检索功能(这是针对已经建成使用的数据库) 查看用户中是否存在ctxsys用户,查询角色里是否存在ctxapp角色.以上两个中的1个不满足(不存在),则说明没有装过全文检索功能 ...
- 未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序
这种错误的可能性有几种,比如: 1.没有安装数据访问组件,需要安装相应版本的数据访问组件: 2.没有安装相应版本的Office客户端,需要安装相应版本的Office客户端: 3.Microsoft.J ...
- django开发过程中静态文件路径配置
在demo项目的settings.py文件中找到 STATICFILES_DIRS STATICFILES_DIRS = ( 'static', #这个名字是项目根目录下的文件夹名称,注意后面有逗号 ...