java对象和类:对象和类的基本概念、构造函数和初始化顺序等
对象和类
基本概念
类、对象、实例、构造、封装、实例字段、方法、状态、继承、对象的行为、状态、标识、类之间的关系依赖、耦合、继承。
static静态字段和静态方法
- 静态字段也被称为类字段,在类第一次被加载的时候创建
- 静态方法不能访问实例字段,而可以访问静态字段。
final关键字
- final修饰基本类型或者不可变类
- final修饰可变类时,只是引用不可变,但是引用的对象可变。
构造函数
- 构造函数通过new来调用,不可以直接调用。
- 重载
- 重载解析
- 返回类型不是数字签名的一部分
- 默认有无参数构造器,但是定义了构造器之后,默认的无参数构造器失效
初始化顺序
- 先初始化静态字段、代码块
- 然后初始化字段、初始化块
- 最后初始化构造函数
- 先初始化调用的构造函数。
- 然后从上往下依次初始化。
代码习惯
- 工厂方法
- 不要返回可变对象
- aClassName
- 不要用对象调用静态方法,而应该用类
- 每个对象都可以有个main,用来单元测试。
- 方法不需要访问对象或者方法只需要访问静态字段的时候可以使用静态方法。
零碎知识点
- java按引用传递
System.out.setout()
可以将System.out
设置为不同的流。因为它是原生方法,可以绕过java访问控制机制。
- 一个方法可以访问所属类的所有对象的私有数据。
- 所有java对象都是在堆中调用的。
- 访问器方法和更改器方法
- 变量不是对象,创建变量的时候还没有对象,更像是创建了指向对象的指针。
包
- 包名
- 域名逆序-项目名-类名
- 只能用import导入一个包,而不能多个包
- 命名冲突时需要import使用的类或者加入完整的包名来指定某个包
- import static 导入静态方法和静态字段,不只是类
- 编译器处理文件(文件分割符和java扩展名)、解释器加载类(点分隔符)。
- 没有修饰符,同一个包中可以访问。
继承
基本概念
- super调用父类
- private不可被继承
- 多态和动态绑定
- 父类变量可以引用子类对象,并且可以使用父类的方法,并自动分辨是子类还是父类的。
- 父类变量不可以使用子类的方法。
- 子类会覆盖和父类相同签名的方法。
- 可协变的返回类型:子类方法的返回类型是父类同签名方法返回类型的子类。
- 静态绑定:private、static、final、构造器。
- 动态绑定:子类到超类
- 方法表查表
- 子类覆写方法的时候,不能低于超类方法的可见性。
- final
- 不允许扩展
- final类中所有方法自动为final方法
- 方法也可以被声明为final,不允许被覆盖
- final类中所有字段不会被声明为final
- final可以加快速度。内联调用可以加快速度。而继承会干扰优化。
- 超类转化为子类
- 抽象类
- 抽象类变量可以引用非抽象子类对象
- 抽象类不可以实例化
- 如果子类没有完全实现抽象方法,子类也是抽象类
- protected
- 默认(不加修饰符)
Object
equals
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public boolean equals(Object other) { if(this == other) return true; if(other == null) return false; if(getClass() != otherObject.getClass()) return false; ClassNmae other = (ClassName)other; return field1 == field2 && Objects.equals(field2, other.field2) && . . .; }
|
- 数组可以用
Array.equals
来检测对应元素是否相等。
hashCode
- Object的hashCode是通过存储地址得出
- String的hashCode是通过字符串内容得出。(内容相同的字符串,散列码相同)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Employee { private String name; private double salary; private LocalDate hireDay; public int hashCode() { return 7 * name.hashCode() + 11 * new Double(salary).hashCode() + 13 * hireDay.hashCode(); }
public int hashCode() { return 7 * Objects.hashCode(name) + 11 * Objects.hashCode(salary) + 13 * Objects.hashCode(hireDay); } public int hashCode() { return Objects.hash(name, salary, hireDay); } }
|
- equals与hashCode定义必须相容,即equals为true的hashCode必须相等。
toString
1 2 3 4 5 6 7 8 9 10
| public String toString() { return getClass().getName() + "[field1=" + field1 + . . . + "]"; }
"" + x;
System.out.println(Arrays.toString(array));
|
泛型
ArrayList
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ArrayList<ClassName> v = new ArrayList<ClassName>();
var v = new ArrayList<ClassName>();
ArrayList<ClassName> v = new ArrayList<> ();
v.add(); v.ensureCapacity(n); ArrayList<ClassName> v = new ArrayList<>(n);
v.trimToSize();
v.set(i, value); v.get(i);
|
- ArrayList和vector
- 与老版本不带类型的ArrayList交互
对象包装器与自动装箱
参数数量可变
1
| public Printstream printf(String fmt, Object... args) {return format(fmt, args);}
|
枚举类
enum
反射
暂时略
接口
- 接口用来描述类应该做什么,而不是指定他们怎么做
- 一个类可以实现一个或多个接口
- 接口不会有实例字段
- java8之前,接口不会实现方法。
- interface和implements
- 接口声明默认public
- 接口字段默认为public static final