chapter 1 对象导论
面向对象程序设计(Object-oriented Programming ,OOP)
chapter 2 一切都是对象
字段和方法
若类的某个成员变量是基本数据类型,即是没有进行初始化,java也会确保它获得一个默认值。
局部变量没有默认值,必须初始化。
方法、参数和返回值
static 关键字
chapter 3 操作符
import static 是导入这个类中的静态方法,然后调用静态方法就可以直接用方法名,而不用"类名.",但要注意导入的方法名有相同的调用时会报错。
java操作符
String 类支持“+”和“+=”。
优先级
关系操作符
对于引用型数据,==和!=比较的是对象的引用,基本类型数据可以直接比较值。equals()可以比较引用型数据的值,equals方法内部是将引用型数据的值转换为基本类型并用== 比较。
字符串操作符
如果表达式以一个字符串起头,那么后续所有操作数都必须是字符串型。
类型转换操作符
chapter 4 控制执行流程
逗号操作符
for循环中用到逗号操作符。
for(int i=1,j=i+10;i<5;i++,j=i*2) { System.out.println("i="+i+",j="+j); }
Foreach 语法
for(float x : f){} //f是一个数组或集合,x是其元素类型。
标签和goto
Java需要使用标签的原因就在于有循环嵌套的存在。Java中没有goto语法,但它是java的一个保留字。
chapter 5 初始化与清理
默认构造器
如果你写的类中没有构造器,则编译器会自动帮你创建一个默认构造器。如果已经定义了一个构造器(无论是否有参数),编译器就不会帮你自动创建默认构造器。
this关键字
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。
在构造器中调用构造器
构造器中只能调用一个构造器,语句必须置于构造器第一句。
构造器只能被构造器调用,不能被其他任何方法调用。
清理:终结处理和垃圾回收
终结条件
class Book{ boolean checkedOut=false; Book(boolean checkOut){ checkedOut=checkOut; } void checkIn() { checkedOut=false; } protected void finalize() throws Throwable { if(checkedOut) { System.out.println("Error:checked out"); } } } public class TerminationCondition { public static void main(String[] args) { Book novel = new Book(true); novel.checkIn(); new Book(true); //while(true){new Book(true);} System.gc(); // } }
垃圾回收器如何工作
引用计数:
class TestA{ public TestB b; } class TestB{ public TestA a; } public class Main{ public static void main(String[] args){ A a = new A(); B b = new B(); a.b=b; //循环引用 b.a=a; a = null; b = null; } }
停止——复制
标记——清扫
成员初始化
方法的局部变量必须初始化才能操作。类的数据成员是基本类型,都会默认赋予初始值。类中对象引用未被初始化,会被设置为null。
指定初始化
- 直接提供初值 int i=99;
- 创建对象并初始化 Depth d=new Depth();
- 通过调用方法提供初值 int i= fun(); int fun(){ return 11; };
构造器初始化
构造器初始化发生在自动初始化(类成员的默认值)之后,构造器初始化实际上是覆盖了字段的默认值。
类中,变量定义的先后顺序决定了初始化顺序,但都会在构造器执行之前初始化。
静态数据初始化
显示的静态初始化
非静态实例初始化
{}代码块在构造器之前执行。
数组初始化
定义数组:int[] a1;
定义并初始化:int[] a1=new int[5]; 元素会被自动赋予默认值。
定义数组并初始化:int[] a1={1,2,3,4,5}; 元素手动赋予初值。
数组是一种特殊的对象:
String y="df"; int[] a1= {2,3,4}; System.out.println(a1.getClass().getName()); // [I System.out.println(y.getClass().getName()); // java.lang.String
打印出的对象名是‘[I’。[表示数组,后面紧跟的数组的类型。
数组对象具有唯一固有成员length。
可变参数列表
printArray(对象1,对象2,对象3);
指定了可变参数,编译器会自动传入的参数列表转换为一个数组,省去显示地编写数组语法。
枚举类型
enum可以在switch语句内使用。
chapter 6 访问权限控制
public、protected、默认空、private
chapter 7 复用类
调用main方法:
初始化基类
继承体系中,构造器中第一行隐式调用父类无参构造器。
名称屏蔽
@Override 注解 表示该方法是重写的方法,如果不存在重写编译器就会报错。
protected 关键字
向上转型
final关键字
final数据
空白final
private final int j; 必须在域的定义处或每个构造器中用表达式对final字段赋值。
final 参数
Java 允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改参数引用所指向的对象。
final 方法
final 和 private 关键字
final 修饰方法无法被子类重写。
private 修饰方法无法被子类重写(必须通过添加@Override来验证),但子类可以存在和父类同名的private修饰的方法,但该方法不是从父类继承来的。
public class A { final int i; public A() { i=4; } public final void fun1() { System.out.println(" A fun1"); } private final void fun2() { System.out.println(" A fun2"); } public void lfun3() { fun3(); } private void fun3() { System.out.println(" A fun3"); } } package cn.test; public class B extends A{ int i; private int b; public void fun2() { System.out.println(" B fun2"); } public void fun3() { //如果给该方法添加@Override,将报编译错误。 System.out.println(" B fun3"); } } package cn.test; public class TestExtends { public static void main(String[] args) { B b = new B(); b.fun3(); b.lfun3(); } }
final 类
final 修饰类,无法被继承。final类中的方法隐式指定为final的。
初始化及类的加载
继承与初始化(P147)
chapter 8 多态
package cn.test; enum Note{ MIDDLE_C,C_SHARP,B_FLAT; } class Instrument{ public void play(Note n) { System.out.println("Instrument.play"); } } class Wind extends Instrument{ public void play(Note n) { System.out.println("Wind.play "+ n); } } public class Music { public static void tune(Instrument i) { i.play(Note.MIDDLE_C); } public static void main(String[] args) { Wind flute = new Wind(); tune(flute); //Upcasting } }
方法调用绑定
前期绑定
后期绑定
产生正确的行为
动态绑定
可扩展性
class Derived extends PrivateOverride{ public void f() { System.out.println("public f()"); } } public class PrivateOverride { private void f() { System.out.println("private f()"); } public static void main(String[] args) { PrivateOverride po = new Derived(); po.f(); //打印:private f() } }
缺陷:域与静态方法
package cn.test; class Super{ public int field=0; public int getField() {return field;} } class Sub extends Super{ public int field=1; public int getField() {return field;} public int getSuperField() {return super.field;} } public class FieldAccess { public static void main(String[] args) { Super sup=new Sub(); System.out.println("sup.field="+sup.field+ ",sup.getField()="+sup.getField()); Sub sub=new Sub(); System.out.println("sub.field="+sub.field+ ",sup.getField()="+sub.getField()+ ",sub.getSuperField()="+sub.getSuperField()); } }
// sup.field=0,sup.getField()=1
// sub.field=1,sup.getField()=1,sub.getSuperField()=0
如果某个方法时静态的,它的行为就不具有多态性。
静态方法是与类,而并非与单个的对象相关联。
继承与清理(P295)
构造器内部的多态方法的行为
协变返回类型(P164)
package cn.test; class Grain{ public String toString() { return "Grain"; } } class Wheat extends Grain{ public String toString() { return "Wheat"; } } class Mill{ Grain process() { return new Grain(); } } class WheatMill extends Mill{ Wheat process() { return new Wheat(); } } public class CovariantReturn { public static void main(String[] args) { Mill m = new Mill(); Grain g = m.process(); System.out.println(g); m=new WheatMill(); g=m.process(); System.out.println(g); } }
用继承进行设计
package cn.test; class Actor{ public void act() {}; } class HappyActor extends Actor{ public void act() { System.out.println("HappyActor"); } } class SadActor extends Actor{ public void act() { System.out.println("SadActor"); } } class Stage{ private Actor actor = new HappyActor(); public void change() {actor=new SadActor();} public void performPlay() {actor.act();} } public class Transmogrify { public static void main(String[] args) { Stage stage = new Stage(); stage.performPlay(); stage.change(); stage.performPlay(); } }
纯继承与扩展
向下转型与运行时类型识别
chapter 9 接口
抽象类和抽象方法
关于编译时和运行时:
ConstantFolding.java文件: public class ConstantFolding { static final int number1=7; static final int number2=4; static int number3=2; static int number4=8; public static void main(String[] args) { int product1=number1*number2; int product2=number3*number4; } } ConstantFolding.class反编译出的java文件: // Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://kpdus.tripod.com/jad.html // Decompiler options: packimports(3) fieldsfirst ansi space // Source File Name: ConstantFolding.java public class ConstantFolding { static final int number1 = 7; static final int number2 = 4; static int number3 = 2; static int number4 = 8; public ConstantFolding() { } public static void main(String args[]) { int product1 = 28;//可见 number1*number2 在编译时处理的。
int product2 = number3 * number4; } }
接口(P172)
接口中的成员变量隐式地加上了static和final。
完全解耦(P174)
通过继承类扩展接口
接口可以继承接口
interface C extends A,B{ } //B,C是接口
组合接口时的名字冲突
适配接口(P181)
接口中的域
接口中的全局变量默认且必须是 static 和 final 的。修饰符自动是 public。
public interface Months { int JANUARY=1,FEBRUARY=2,MARCH=3,APRIL=4,MAY=5,JUNE=6, JULY=7,AUGUST=8,SEPTEMBER=9,OCTOBER=10,NOVEMVER=11,DECEMBER=12; }
可以反编译Months.class,所有字段都自动添加 public static final ~
初始化接口中域
接口中定义的域不可以是“空final”,但可以使用非常量表达式初始化。
由于是static修饰,在类第一次加载时初始化。
嵌套接口
接口与工厂
来源:https://www.cnblogs.com/mryangbo/p/10097521.html