- 合成 - 在新类里简单地创建原有类的对象 - 新类由现有类的对象合并而成
- 继承 - 创建一个新类,将其作为现有类的一个“类型”
//对于非基本类型的对象来说,只需将句柄置于新类即可;而对于基本数据类型来说,则需在自己的类中定义它们。 // composition for code reuse class WaterSource{ private String s; WaterSource(){ System.out.println("WaterSource()"); s = new String("Cnstructed"); } public String toString(){ return s; } } public class SprinklerSystem { private String valve1, valve2, valve3, valve4; WaterSource source; int i; float f; void print(){ System.out.println("valve1 = " + valve1); System.out.println("valve2 = " + valve2); System.out.println("valve3 = " + valve3); System.out.println("valve4 = " + valve4); System.out.println("i = " + i); System.out.println("f = " + f); System.out.println("source = " + source); } public static void main(String[] args) { SprinklerSystem x = new SprinklerSystem(); x.print(); } } /* valve1 = null valve2 = null valve3 = null valve4 = null i = 0 f = 0.0 source = null */
如希望句柄得到初始化,可在下面这些地方进行:
- 在对象定义的时候。这意味着它们在构建器调用之前肯定能得到初始化。
- 在那个类的构建器中。
- 紧靠在要求实际使用那个对象之前。这样做可减少不必要的开销——假如对象并不需要创建的话。
// Inheritance syntax & properties class Cleaner{ private String s = new String("Cleaner"); public void append(String a){s += a;} public void dilute(){append("dilute()");} public void apply(){append("apply()");} public void scrub(){append("scrub()");} public void print(){System.out.println(s);} public static void main(String[] args) { Cleaner x = new Cleaner(); x.dilute();x.apply();x.scrub(); x.print(); } } public class Detergent extends Cleaner { // change a method public void scrub(){ append("Detergent.scrub()"); super.scrub(); // call base-class version } // add methods to the interface public void foam(){append("foam()");} // test the new class public static void main(String[] args) { Detergent x = new Detergent(); x.dilute(); x.apply(); x.scrub(); x.foam(); x.print(); System.out.println("Testing base class:"); Cleaner.main(args); } } /* Cleanerdilute()apply()Detergent.scrub()scrub()foam() Testing base class: Cleanerdilute()apply()scrub() */
// Constructor calls during inheritance /** * 可以看出,构建是在基础类的“外部”进行的,所以基础类会在衍生类访问它之前得到正确的初始化。 即使没有为 * Cartoon()创建一个构建器,编译器也会为我们自动合成一个默认构建器,并发出对基础类构建 器的调用。 * */ class Art { Art() { System.out.println("Art constructor"); } } class Drawing extends Art { Drawing() { System.out.println("Drawing constructor"); } } public class Cartoon extends Drawing { Cartoon() { System.out.println("Cartoon constructor"); } public static void main(String[] args) { Cartoon x = new Cartoon(); } } /* * Art constructor * Drawing constructor * Cartoon constructor */
在衍生类构建器中,对基础类构建器的调用是必须做的第一件事情
final 数据:
许多程序设计语言都有自己的办法告诉编译器某个数据是“常数”。
- 编译期常数,它永远不会改变 - 编译器可将常数值“封装”到需要的计算过程里。也就是说:计算可在编译期间提前执行,从而节省运行时的一些开销。在Java中,这些形式的常数必须属于基本数据类型。
- 在运行期间初始化的一个值,不希望它发生变化
// can be compile-time constants final int i1 = 9; static final int I2 = 99; //typical public constants public static final int I3 = 39; // cannot be compile-time constants final int i4 = (int)(Math.random()*20); static final int i5 = (int)(Math.random()*20);
final 参数变量
意味:在一个方法内部,我们不能改变参数变量句柄指向的东西。
//Using "final" with method arguments class Gizmo { public void spin() { } } public class FinalArguments { void with(final Gizmo g) { // ! g = new Gizmo(); // Illegal -- g is final g.spin(); } void without(Gizmo g) { g = new Gizmo(); // OK -- g not final g.spin(); } // void f(final int i) { i++; } // Can't change // You can only read from a final primitive: int g(final int i) { return i + 1; } public static void main(String[] args) { FinalArguments bf = new FinalArguments(); bf.without(null); bf.with(null); } }
final方法:
- 第一个是为方法“上锁”,防止任何继承类改变它的本来含义。
- 程序执行的效率。
Think in Java 写道将一个方法设成 final 后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。
只要编译器发现一个final 方法调用,就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。
相反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销。
final方法体执行效率一般会高一些:
- replace the method call:push arguments on the stack, hop over to the method code and execute it, hop back and clean off the stack arguments, and deal with the return value
- with a copy of the actual code in the method body
final 类:
表明自己不希望从这个类继承,或者不允许其他任何人采取这种操作。
换言之,出于这样或那样的原因,我们的类肯定不需要进行任何改变;或者出于安全方面的理由,我们不希望进行子类化(子类处理)。
所以与我们将一个方法明确声明为final 一样,编译器此时有相同的效率选择。
装载 - 首先parent、然后child
初始化 - 首先parent的static、然后child的static
相关推荐
很值得一看的书籍,很多人都推荐,适合有一定java基础的人学习提高
JAVA思想中文版,CHM格式.
Think-In-Java-Code Thinking In Java 书中源码以及课后练习代码(从第7章开始随着看书的进度一步步更新) 第七章 复用类 7.1 组合语法 7.2 继承语法 7.2.1 初始化基类 7.3 代理 7.4 结合使用组合和继承 7.4.1 确保...
作者:贯穿本书,我试图在您的大脑里建立一个模型——或者说一个“知识结构”。这样可加深对语言的理解。若遇到难解之处,应学会把它填入这个模型的对应地方,然后自行演绎出答案。事实上,学习任何语言时,脑海里有...
Think Data Structures Algorithms and Information Retrieval in Java-OReilly(2017)
Think in java 源码构建编译
think in java 源码整理,应该算是比较全面的,有需要的朋友可以下下来看下
Think in java 的代码源码,里面很详细的习题详解
java think in java (英文第四版)至今为止 被认为是java教程之中权威作品之一
think-in-effective-teamwork.pptx
Think Data Structures in Java 英文azw3 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
think in java 第四版 源码以及作业 eclipse版本 包含jar包 可以直接导入eclipse
1.5.1 改善基础类 1.5.2 等价和类似关系 1.6 多形对象的互换使用 1.6.1 动态绑定 1.6.2 抽象的基础类和接口 1.7 对象的创建和存在时间 1.7.1 集合与继承器 1.7.2 单根结构 1.7.3 集合库与方便使用集合 ...
对java模式的介绍,因为think in java太厚了,所以分离出来出版
Think-In-Go
这是java编程思想中的练习题,自己感觉不错,上传上去给大家分享~~~~~
抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善基础类 1.5.2 等价和类似关系 1.6 多形对象的互换使用 1.6.1 动态绑定 ...1.11 Java和因特网
Think in Java(美)Bruce Eckel 著 陈昊鹏 译 引言 同人类任何语言一样,Java为我们提供了一种表达思想的方式。如操作得当,同其他方式相 比,随着问题变得愈大和愈复杂,这种表达方式的方便性和灵活性会显露无遗。 ...
这个是我花钱买的,现在献给大家......