《Java编程思想》读书笔记 —— 类与接口。
第5章 初始化与清理
1.构造器初始化 initialize()
Java 采用构造器(constructor)初始化
和创建
对象,两个过程捆绑在一起。
类中没有构造器即构造函数时,编译器会自动创建一个默认构造器;反之,则不会自动创建。
2.方法重载:每个重载方法都有一个独一无二的参数类型列表。
3.this 关键字只能在方法内部使用,表示“调用方法的那个对象”。
static 方法就是没有 this 的方法,可以在没有创建对象的情况下仅仅通过类名本身调用 static 方法。
4.垃圾回收 finalize()
- 对象可能不被垃圾回收。
- 垃圾回收并不等于“析构”。
- 垃圾回收只与内存有关。
5.成员初始化及构造器初始化
Java 尽力保证:所有变量在使用前都能的到恰当的初始化。
6.初始化顺序:在类的内部,成员变量会在任何方法(包括构造器)调用之前初始化。
含静态数据的初始化:先静态对象后非静态对象。
7.声明数组变量
int[] a; // 首选的方法
int a[]; // 效果相同,但不是首选方法
初始化:
int[] a = new int[5];
int[] a = {1, 2, 3, 4, 5};
可变参数列表:
void fun (Object... args){
for(Object obj : args){
system.out.printf(obj + "");
}
}
8.枚举类型 enum
public enum Spiiness{
NOT, MILD, MEDIUM, HOT, FLAMING
}
第6章 访问权限控制
访问权限(由大到小):public、protected、包访问权限和 private 。
- default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
- public : 对所有类可见。使用对象:类、接口、变量、方法。
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
第7章 复用类
复用代码有两种方法:在新类中产生现有类的对象(组合);按照现有类的类型创建新类(继承)。
1.组合,将对象的引用置于新类中即可。
2.继承,使用 extends 实现,导出类自动获得基类的所有域和方法。
没有参数的初始化构建过程,从基类“向外”扩散;带参数的构造器使用 super 显式地调用基类构造器语句。
3.代理是一种介于组合和继承的中庸之道,将成员对象置于构造地类中(类似组合),与此同时在新类中暴露该成员对象的所有方法(类似继承)。
public class SpaceShipDelegation {
private String name;
private SpaceShipControls controls =
new SpaceShipControls();
public SpaceShipDelegation(String name) {
this.name = name;
}
// Delegated methods:
public void back(int velocity) {
controls.back(velocity);
}
public void forward(int velocity) {
controls.forward(velocity);
}
public static void main(String[] args) {
SpaceShipDelegation protector =
new SpaceShipDelegation("NSEA Protector");
protector.forward(100);
}
}
4.向上转型
新类和基类之间的关系,新类是现有类的一种类型。
基类所有的方法和属性在导出类中也同样存在,导出类可以转化为基类,即向上转型。
5.final 关键字,指“这是无法改变的”,可用在 数据、方法和类 上。
final 数据:一个永不改变的编译常量;一个运行时被初始化的值,而不希望被改变。
final 方法:方法锁定,在继承中保持行为不变,并且不会被覆盖;效率。
final 类:不允许继承。
final 强调不允许改变,static 强调只有一份。
6.初始化及类的加载
//: reusing/Beetle.java
// The full process of initialization.
import static net.mindview.util.Print.*;
class Insect {
private int i = 9;
protected int j;
Insect() {
print("i = " + i + ", j = " + j);
j = 39;
}
private static int x1 =
printInit("static Insect.x1 initialized");
static int printInit(String s) {
print(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");
public Beetle() {
print("k = " + k);
print("j = " + j);
}
private static int x2 =
printInit("static Beetle.x2 initialized");
public static void main(String[] args) {
print("Beetle constructor");
Beetle b = new Beetle();
}
}
/* Output:
static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39
*/
第8章 多态
多态作用是消除类型之间的耦合关系,允许将多种类型视为同一类型处理。
1.方法调用绑定
将一个方法调用同一个方法主题关联起来被称作绑定:
前期绑定:在程序执行前进行绑定;
后期绑定:运行时根据对象的类型进行绑定。
Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定
public class Shape {
public void draw() {}
public void erase() {}
}
class Circle extends Shape {
public void draw() { System.out.println("Circle.draw()"); }
public void erase() { System.out.println("Circle.erase()"); }
}
class Square extends Shape {
public void draw() { System.out.println("Square.draw()"); }
public void erase() { System.out.println("Square.erase()"); }
}
public static void main(String[] args) {
Shape shape = new Circle();
shape.draw();
}
/* Output:
Circle.draw()
*/
因为继承,将 Shape 引用指向一个新创建的 Circle 对象不会有任何问题;
又因为时后期绑定,会使得程序能够正确调用 Circle.draw() 。
第9章 接口
接口和内部类为我们提供了一种将接口和实现分离的更加结构化的方法。
1.抽象类和抽象方法
抽象方法是不完整的,仅有声明而没有方法体。
abstract void f();
包含抽象方法的类叫做抽象类;如果一个类包含一个或多个抽象方法,该类必须被定义为抽象的。
继承自抽象类的新类需要提供所有抽象方法的定义,否则也是抽象类。
2.接口
interface 关键字产生一个完全抽象的类,它根本就没有提供任何具体实现。
要让一个类遵循特定接口或者一组接口,需要使用 implements 关键字。
interface Instrument {
int VALUE = 5;//final && static
void play(String s);
void adjust();
}
class Wind implements Instrument {
public void play(String s) {
System.out.print("Wind.play()");
}
public void adjust() {
System.out.println(""Wind.adjust()"");
}
}
- 接口中的方法默认是 public 的,不需要显式声明为 public 的;
- 接口中的任何域都自动是 static 和 final 的;
- 当要实现一个接口时,在接口中被定义的方法必须被显式声明为 public 的,否则只能得到默认的包访问权限。
第10章 内部类
将一个类的定义放在另一个类的定义的内部,这就是内部类。
public class Parcel1 {
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() { return label; }
}
// Using inner classes looks just like
// using any other class, within Parcel1:
public void ship(String dest) {
Destination d = new Destination(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel1 p = new Parcel1();
p.ship("Tasmania");
}
}
/* Output:
Tasmania
*/
1.内部类不仅是一种名字隐藏和组织代码的模式,还拥有与其他外围类的所有元素的访问权限。
2.使用 .this 与 .new
.this 用来生成对外围对象的引用。
public class DotThis {
void f() { System.out.println("DotThis.f()"); }
public class Inner {
public DotThis outer() {
return DotThis.this;
// A plain "this" would be Inner's "this"
}
}
public Inner inner() { return new Inner(); }
public static void main(String[] args) {
DotThis dt = new DotThis();
DotThis.Inner dti = dt.inner();
dti.outer().f();
}
}
/* Output:
DotThis.f()
*/
.new 用来创建外部类对象的内部类对象。
public class DotNew {
public class Inner {}
public static void main(String[] args) {
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner();
}
}
3.匿名内部类
public class Parcel7 {
public Contents contents() {
return new Contents() { // Insert a class definition
private int i = 11;
public int value() { return i; }
}; // Semicolon required in this case
}
public static void main(String[] args) {
Parcel7 p = new Parcel7();
Contents c = p.contents();
}
}
4.嵌套类
如果不需要内部类对象与外部类对象之间的联系,内部类声明可为 static ,通常称为嵌套类。
- 创建嵌套类对象并不需要其外围对象。
- 不能从嵌套类对象中访问非静态的外围类对象。
5.闭包和回调
闭包(Closure)是一种能被调用的对象,它保存了创建它的作用域的信息。
回调(Callback)程序在特定时间自己回头调用预先实现的方法。
参考资料
1、Java 修饰符
http://www.runoob.com/java/java-modifier-types.html
2、《Java编程思想》读书笔记 第九章 接口
https://zhuanlan.zhihu.com/p/25597956
3、Java—内部类(二)—实现闭包与回调
http://blog.csdn.net/yuwenhao07/article/details/53607117
评论 (0)