子类
public class A extends B{
}
1子类可以复写超类的方法,对于父类的数据 也只能通过父类的方法访问
当覆写方法 想调用父类的同名方法 时, 可以加 super. 实现
2 子类构造器 可以调用父类的 构造器 super(…..,…..) 必须在第一行就调用
3 Java的多态 :一个父类类型的变量可以引用子类,调用方法时 虚拟机知道实际引用的对象类型,因此能够正确地调用相应的方法
4 Java 不支持多继承
5 子类数组的引用 可以转化为 超类 数组的引用 ,但不要通过该引用 将超类存储在其中 会引发异常
6 返回类型不是签名的一部分,因此,在覆盖方法时,一定要保证返回类型的兼容性。允许子类将覆盖方法的返回类型定义为原返回类型的子类型
7 虚拟机预先为每个类创建了一个方法表,其中列出了所有方法的签名和实际调用的方法
8 final 修饰 类 可以防止 该类 被继承
9 final 修饰 方法 可以防止 该方法被 覆写
10 可以通过类型转换 将一个 超类变量 转换为 子类变量 ,如果确实引用的是超类对象,运行时会抛出异常
11 这种转换只能在继承体系内转换, 在将超类转换成子类之前,应该使用instanceof进行检查。
12 通过类型转换调整对象的类型并不是一种好的做法,尽量减少使用类型转换 和 instanceof
13 如果父类有个方法 无法提供具体实现,只能子类实现 可以定义为抽象方法
14 具有抽象方法的类 是抽象 类, 必须用 abstract修饰类
public abstract class A{
public abstract String getDescription();
}
15 抽象类可以有具体的数据和方法 ,抽象类不能被实例化 ,其非抽象的子类可以
16 protect 修饰 数据 和方法 可以让子类访问 不推荐修饰数据 破坏OOP原则 修饰方法可以 (如object 的 clone方法)
Object, 所有类的超类
1 如果没有明确地指出超类,Object就被认为是这个类的超类
2 可以使用Object类型的变量引用任何类型的对象
3 equals()(默认是比较变量引用的地址,即 ==)
为了防止 null ,使用Objects.equals(a, b) 更适合
在判断类型相同的时候 :
如果子类能够拥有自己的相等概念,则对称性需求将强制采用getClass进行检测。
如果由超类决定相等的概念,那么就可以使用instanceof进行检测,这样可以在不同子类的对象之间进行相等的比较
4 编写equals 建议顺序:
判断 this == otherObject 是否引用同一对象 (优化)
判断 otherObject == null 是否为空
判断 getClass () 或者InstanceOf
将OtherObject 转换为 this 的类别
对所有的域进行比较
5 可以使用静态的Arrays.equals方法检测相应的数组元素是否相等
6 HashCode 由对象导出的一个整数值 (默认的HashCode 根据 地址定)
HashCode方法要和equals方法同步,
同样 为了防止 null 异常 用 Objects.hashCode() 更好
7 对于一些基本类型,使用类似于Double.hashCode() 可以避免 创建 Double对象
8 toString() 方法,返回对象的字符串
泛型数组列表
ArrayList
1 数组列表自动扩展容量的便利增加了访问元素语法的复杂程度
staff.set(i,new Employee())
staff.get(i)
参数变量可变的方法
public static double max(double... args); //args 就是 double[]
枚举类
public enum Size{A("1"),B("2"),C("3");
private String number;
private Size(String number){this.number = number;}
public String getNumber(){return this.numebr;}
};
1 枚举类是一个类 ,刚好有3个实例,不要构造新对象
2 枚举类型的值对比的时候,直接== 就好了 不要用equals
3 需要的话,可以在枚举类型中添加一些构造器、方法和域。 构造器只是在构造枚举常量的时候被调用
4 每个枚举实例都继承了很多方法 最常用的有 toString
Size.A.toString 可以得到”A”
其逆方法为 valueOf , Enum.valueOf(Size.class,”A”);
反射
能够分析类能力的程序称为反射(reflective)
1 Class类
Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识,通过Class来
Object.getClass() 会返回一个Class对象
方法 getName() 返回类的名字(全类名 包括了包名)
静态Class.forName()方法 可以通过 全类名字符串 获得Class类实例
还可以通过 类型.class 获得class对象 如 A.class
2 虚拟机为每个类型管理一个Class对象。因此,可以利用==运算符实现两个类对象比较的操作
3 class实例 有一个 newInstance() 方法 可以构建实例 该方法调用无参的构造器,如果没有 跑出异常
如果想要提供参数构造对象, 必须使用Constructor类中的newInstance方法
4 forName 抛出的异常属于非检查异常,无法预测,用try catch 进行处理
5 反射最重要的内容 是 检查类的结构 ,主要的类:
Field 类 ,Method 类 , Constructor类
都有getName 用于返回 名称 ,getModifiers 方法 返回位信息 描述 public static等
这个位信息 可以用Modifier类的静态方法 解析 如 isPublic isPrivate等
Field 类 有 getType 方法 用于 返回域的 class 信息
method 和 constructor 有 报告 参数类型的方法, method还有返回 类型的方法
通过class 类的 getFields getMethods getConstructors 可以 返回public 的 filed method constructor 的数组 包括超类
而 getDeclaredFields等 可以获得所有声明的 但不包括超类的
getField可以传入String 获取指定的Field对象
通过 filed 的 get方法 ,参数为对象,可以获得该对象的field的实际值 ,(默认只能获取 public 的 field)
如果确实要访问私有域 需要加 field.setAccessible(true)
可以get 就可以 set 通过 field的set方法 可以设置指定对象的 值
6 反射机制允许调用任意的方法 Method 有个invoke方法 ,Object invoke(Object obj, object… args),对于静态方法 第一个设置为NULL
getMethods(String,Class… args) 可以获得指定的方法
利用反射调用方法 类似于 函数指针 ,很容易出错, 如传错了参数 就会报错
7 而且利用反射调用函数更慢,建议仅在必要的时候才使用Method对象,最好使用接口 和lambda表达式