1,继承 继承关系有替换和扩展两种
替换是指子类完全复写基类的方法
扩展则是另有新的方法,扩展接口
2, this关键词只能用于方法内部 他负责返回调用这个方法的reference.相当于返回本身对象。
3,子类的初始化顺序:a,在进行其他工作之前,分配给这个对象会被先初始化为二进制的零
b,调用父类的构造函数
c,按照声明顺序初始化本类成员
d,执行本类构造函数
4,OOP语言采用的是后绑定(Late binding)当你向某个对象发送消息的时候,不到运行时,系统不能确定到底该调用哪段代码。编译器只能保证这个方法的存在,并且还要检查参数和返回值的类型。但不知道具体要执行哪一段代码。JAVA用了一些特殊的代码来代替绝对调用,代码用存储在对象中的信息来计算方法的地址
5,我们把派生类当作基类来用的过程称之为上传(upcast).
Shape----circle
Do(Shape shape){…….} 可以将circle当做一个Shape传进去.
6,abstract方法只能存在于abstract类中。如果有类继承这个abstract类,要么来实现这个方法,要么他也是个abstract类.
7,在程序中单独运行的片断 就是线程
8,程序运行时数据可以存储在以下六个位置:
A 寄存器(registers) 由编译器分配
B 栈(stack) 可以通过栈指针直接访问(常规内存区)
C 堆(heap) 比栈要灵活,但慢(多用途内存池)
D 静态存储(static storage) 内存中固定位置
E 固定存储 (constant storage)常量通常都存在程序中,这样就不会被改动了
F 非内存的存储 (Non-RAM storage)
9, 静态的变量或者方法 两种调用方式,一,实例调用(所有实例共享) 二,类调用
创建对象顺序
1 搜寻classpath 装载.class 初始化static 数据对象
2 new 之后,分配足够堆内存
3 内存先被清零,自动把primitive类型的成员赋上缺省的值。将reference设成null
4 执行定义成员数据所做的初始化
5 执行构造函数
显式的静态初始化,有时称为static块
Class Spoon{
Static int I;
Static {
I =67;
}
}
访问控制权限 public protected package private
继承是对要对已有的类做一番改造,以此获得一个特殊版本.就是将一个较为抽象的类改造成一个能使用于特定需求的类.继承要表达的是一种"是(IS-A)"关系,而合成是表达"有(HAS-A)"关系.
常量用于两种情况
1,编译时的常量 static final int VAL_ONE = 9;
2,运行时初始化的值 final int i1 = rand.nextInt(20); static final int i2 = rand.nextInt(20);
初始化顺序
class Insect {
private int i = print("insect.i 被初始化");
protected int j ;
Insect(){
System.out.println("Insect 构造方法执行 i="+i+"j="+j);
j=90;
}
private static int x1 = print("static insect.x1 被初始化");
static int print(String s){
System.out.println(s);
return 100;
}
}
class Beetle extends Insect{
private int k = print("beetle.k 被初始化!");
private static int m = print("static beetle.m 被初始化!");
Beetle(){
System.out.println("Beetle 构造方法执行 k="+k+"j="+j);
}
public static void main(String[] args) {
System.out.println("beetle....");
Beetle beetle = new Beetle();
}
}
结果如下:
static insect.x1 被初始化
static beetle.m 被初始化!
beetle....
insect.i 被初始化
Insect 构造方法执行 i=100j=0
beetle.k 被初始化!
Beetle 构造方法执行 k=100j=90
分析:当运行Beetle的时候,第一件事是访问Beetle.main(),于是loader(装载器)会去寻找经编译的Beetle.class文件,装载过程中注意到它有个一个基类,于是继续装载基类,如果基类还有基类,那么会继续装载.下一步它会执行"根基类"的static初始化,然后是下一个派生类的static初始化.装载完毕之后,可以创建对象了.首先,对象里的所有primitive都会设置成缺省值,reference会设置成为null,初始化基类的primitive and reference 执行构造方法,然后是派生类.
interface and abstract
如果知道这样东西可能会是基类的话,就应该优先考虑把它做成interface,只有在不得不定义方法或成员变量的情况下,你才能把它改成abstract类,或者改成实体类.
接口可以嵌套在类里面,也可以嵌套在接口里面,在类里面,可以是private的(只能在定义它的类里面实现) 也可以是public的 在接口里面,只能是public的
内部类
一种隐藏名字和组织代码的方式.如果创建了一个内部类,那么这个内部类的对象,就与创建它的宿主类的对象产生了某种关系,这样它就能访问宿主类对象的成员了,此外还能访问宿主类的所有元素.
异常处理
想要创建自己的异常,必须继承已有的异常,最好是比较相近的.一般不用写什么代码,构造函数由编译器自动创建.对异常来说,最重要的是这个类的名字.
String getMessage()
String getLocalizedMessage()
void printStackTrace()
void printStackTrace(PrintStream)
void printStackTrace(java.io.PrintWriter)
重抛异常
catch(Exception ex){System.err.println("exception"); throw e}
重抛会把异常送到更高一层的处理程序中。同一个TRY区块的其他CATCH子句都将被忽略.此外,它还会保留异常对象里的所有信息,这样捕获这个异常的上一层的异常处理程序就能提取这个对象中的所有信息了.
编程的时候编译器会强制要求你写出所有的其他的处理程序,所以你能忽略RuntimeException及其子类,原因就是它表示编程错误:
1,一种你无法预料的错误,比如不在控制之内的null reference
2,一种由于"程序员忘了检查他应该检查的错误条件"而造成的错误,比如(ArrayIndexOutOfBoundsException)
在有break和continue语句的情况下,finally也会得到执行.