JavaSE查缺补漏(四)
一、abstract 抽象类
- abstract和final不能联合使用,这两个关键字是对立的
- 抽象类的子类可以是抽象类
- 抽象类无法实例化,但是抽象类有构造方法,这个方法是供子类使用的
- 抽象类最大的作用就是降低实现类实现接口的难度(个人理解)
- 抽象类中不一定有抽象方法,但抽象方法必须在抽象类中
- 非抽象类集成抽象类,必须实现其抽象方法
//用abstract没有方法体的方法,抽象方法
public abstract void doSome();
二、(面试题)java语言中没有方法体的方法不一定是抽象方法 ,例如:
//前面没有abstract修饰,有一个native,表示底层调用C++写的
//动态链接库程序,调用JVM本地程序
public native int hashCode();
三、interface 接口
- 接口中只包含常量和抽象方法
- public abstract可以省略
//public abstract int sum(int a,int b);
//省略public abstract
int sum(int a,int b);
- 接口中所有的原始都是public的,公开的
- 常量的public static final可以省略
- 实现接口需要implements关键字
- 接口和接口之间没有继承关系也可以强制类型转换,编译可以通过,但是运行时可能出现ClassCastException异常(除非实际内存中的对象是实现了这两个接口),还是要使用instanceof判断
四、类与类之间的关系
- is a 什么是一个什么,表示继承关系
- has a 什么有一个什么 表示关联关系,通常以属性的形式存在
- like a 什么像一个什么 表示实现关系,通常表示类实现接口
五、将class文件编译到当前目录下
DOS命令:javac -d . HelloWorld.java
- -d 带包编译
- . 表示表示编译生成的东西放到当前目录下
六、import
- import语句只能出现在package页语句之下,class声明语句之上
- 可以使用星号表示所有
- java.long.*下的类不需要导包
七、访问控制权限
访问控制权限 | 本类 | 同包 | 子类 | 任意位置 |
---|---|---|---|---|
public(公开的) | 可以 | 可以 | 可以 | 可以 |
protected(受保护的) | 可以 | 可以 | 可以 | 不行 |
默认 | 可以 | 可以 | 不行 | 不行 |
private(私有的) | 可以 | 不行 | 不行 | 不行 |
修饰接口和类只能是默认和public
八、toString
- 源码
public String toString(){
//返回类的名字加@加地址的哈希值
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
九、equals
- 默认采用的是“==”来判断两个java对象是否相等
十、finalize方法
- 源码
protected void finalize() throws Throwable{}
- System.gc();可以建议启动垃圾回收器
十一、hashCode()方法,计算对象内存地址的哈希值
十二、clone()方法
- 分为深克隆和浅克隆(现在不会)
十三、内部类(基本不用,降低代码可读性)
- 静态内部类(static)
- 实例内部类
- 局部内部类(方法中)
- 匿名内部类
class Test01{
// main方法,入口
public static void main(String[] args){
// 调用MyMath中的mySum方法。
MyMath mm = new MyMath();
//并不是直接new了接口,而是创建了一个没有名字的实现类,并创建了对象
//后面的{}代表了对接口的实现
mm.mySum(new Compute(){
public int sum(int a, int b){
return a + b;
}
}, 200, 300);
}
}
// 负责计算的接口
interface Compute{
// 抽象方法
int sum(int a, int b);
}
// 数学类
class MyMath{
// 数学求和方法
public void mySum(Compute c, int x, int y){
int retValue = c.sum(x, y);
System.out.println(x + "+" + y + "=" + retValue);
}
}
十四、数组
- 直接传递静态数组
printArray(new int[]{1,2,3})
- 数组扩容是先新建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大容量数组中,效率比较低
int[] src = {1,2,3,4,5};
int[] dest = new int[10];
//第一个0是源的起点下标,第二个0是目标的起始下标,第五个参数是拷贝多长
System.arraycopy(src,0,dest,0,src.length);