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