Java-思想规范

Java-思想规范

1. 面向对象六大原则

1.1 单一职责原则

  • 两个完全不一样的功能不能放在一个类中,一个类应该是一组相关性很高的函数、数据的封装。
  • 如何划分一个类的职责因人而异,但要根据个人的经验、具体的业务来定,比如图片加载和缓存应该放在不同的类中。

1.2 开放关闭原则

  • 软件中的函数、对象,应该对于扩展是开放的,对于修改是封闭的。
  • 当软件需要变化时,应该尽量通过扩展的方式,而不是修改已有的代码。

1.3 里氏替换原则

  • 所有引用基类的地方,必须能透明地使用其子类的对象。
  • 只要父类出现的地方,子类就可以出现,替换为子类也不影响。但是反之不行。
  • 核心是抽象,抽象又依赖于继承。建立抽象,通过抽象建立规范,具体的实现在继承时替换掉。往往和开闭原则一起,通过接口和抽象的方式。

1.4 依赖倒置原则

  • 实现类直接不直接发生依赖关系,其依赖关系通过接口或抽象类产生,即:面向接口编程。
  • Java 中抽象指接口或抽象类不能直接被实例化;细节是实现接口或继承抽象类的实现类,可以直接被实例化。

1.5 接口隔离原则

  • 类之间的依赖关系应该建立在最小接口上。让客户端依赖的接口尽可能小,解耦合。

1.6 迪米特原则

  • 最少知识原则:一个对象应该对其他对象有最少的了解。因为关系越密切,则耦合度越大。
  • 只与直接的朋友通信。

2. 继承和多态

重写和重载?


3. 自动装箱和自动拆箱

  • 自动装箱:int i = 0; Integer n = i; 内部调用:n = Integer.valueOf(i);
  • 自动拆箱:Integer i = 0; int n = i; 内部调用:n = i.intValue();

4. Java 泛型

泛型类在编译后其泛型信息会被擦除为 Object,泛型会被转移到实际使用了泛型的变量或方法中(如果没有则彻底丢失存根),所以编译后的类已经丢失了自己的泛型信息,无法通过反射获取自己的泛型,除非其继承自某个使用了泛型的父类,则 getClass().getGenericSuperclass() 才会保存父类的泛型信息。

而接口则可以理解为一种特殊的父类,因为接口无法直接实例化为一个对象,匿名构造类也是编译时通过匿名类实现该接口后返回来实现的,因此对于实现了接口的类,可以通过 getClass().getGenericInterfaces() 来获取接口信息,因为接口实际上可以看作实现类的"父类",所以获取接口信息时就能获取到接口的泛型信息。


5. Object方法

  • Object():构造方法。
  • clone():用来另存一个当前存在的对象。
  • equals(Object):用于确认两个对象是否相同。
  • finalize():这个函数在进行垃圾回收的时候会用到,匿名对象回收之前会调用到。
  • getClass():返回一个当前类的 Class 全名。
  • hashCode():用于获取对象的哈希值,这个值的作用是检索。
  • notify():用于随机通知一个持有对象的锁的线程获取操作权限。
  • notifyAll():用于通知所有持有对象的锁的线程获取操作权限。
  • toString():返回一个String对象,用来标识自己。
  • wait():用于让当前线程失去操作权限,当前线程进入等待序列。
  • wait(long):用于设定下一次获取锁的距离当前释放锁的时间间隔。
  • wait(long,int):用于设定下一次获取锁的距离当前释放锁的时间间隔。

6. 抽象类和接口的区别

6.1 使用上的区别

  • 抽象类使用abstract修饰;
  • 抽象类不能实例化,即不能使用new关键字来实例化对象;
  • 含有抽象方法(使用abstract关键字修饰的方法)的类是抽象类,必须使用abstract关键字修饰;
  • 抽象类可以含有抽象方法,也可以不包含抽象方法,抽象类中可以有具体的方法;
  • 如果一个子类实现了父类(抽象类)的所有抽象方法,那么该子类可以不必是抽象类,否则就是抽象类

6.2 逻辑上的区别

抽象类的本质还是一个类,可以为子类定义所需的逻辑,本质上是对子类的抽象,也能通过实际实现方法,直接统一子类的行为,而接口更像是预先安排一些功能,而对于实现了这个接口的类的外部而言,其他类并不需要关心这个类具体的功能或实现,只需要根据其实现的接口就能调用相关的功能。

6.3 优缺点比较

  • 抽象类可以定义方法的默认实现,也即可以预定义其子类的主体功能。但一个类只能继承自一个父类,所以抽象类需要高度抽象才具有价值,但高度抽象又会降低对子类主体功能的控制性。
  • 一个类可以实现多个接口,接口可以定义一个类的行为。但实现一个接口时,就必须实现该接口内的所有方法。