概述
三大特征:封装 + 继承 + 多态
封装
封装隐藏了内部实现细节,只暴露出接口。对外暴露出尽可能少的细节,当内部细节实现需要改变时,外面可以尽可能少地进行更改或者不进行更改
耦合
一个类调用了另一个类,那么这两个类就具有耦合关系。
- 低耦合 -> 调用封装的接口 => 内部细节更改时,外部无需改动 => 降低自身和依赖软件之间的相互关系
- 高耦合 -> 调用封装的接口的内部细节 => 内部细节更改时,外部需要改动
继承
DRY => Do not Repeat Yourself => 事不过三,三则重构 => 继承的本质是提炼出公共代码,避免重复
单根继承 & 单一继承
当类不继承任何其他类时,默认继承了 Object
=> 可以保证 Java 世界中的所有对象都拥有某个行为,因为所有的对象都继承了 Object
在 Java 中一个类只能继承一个类,不能同时继承多个类
多重继承 => 当继承的类中具有相同的行为时,不知道应该去选择哪一个行为 => 菱形继承
向上 | 向下转型
- 一个子类类型的对象永远是一个父类类型的对象
- 当需要一个父类型时,总可以传递一个子类型
- 向上转型是安全的,向下转型是不安全的
- 如果要进行不安全的转型,必须进行强制转换,并且在过程中可能会抛出异常
java.lang.Object
equals
Object.equals()
=> 比较两个对象的内容是否相等 => 当重写 equals()
方法时,要同时重写 hashCode()
方法
toString
用来对一个对象提供一个字符串表示 => 可以用来看一下对象中的数据 => 可以通过重写 Object.toString()
方法来让数据更好的展示 => System.out.println(Animal)
打印一个对象时,会自动调用对象的 toString()
方法
public class Animal {
String name;
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
override
重写行为 => 方法签名没有改变,方法的内部细节重写 => 最佳实践:永远使用 @Override
注解
多态
多态 => 面向对象的灵魂 => 一个方法表现出了不同的形态 => 不同的类中的方法有不同的实现
-
实例方法默认是多态的 => 在运行时根据
this
来决定调用哪个方法 => 例:多个类继承了同一个类,覆盖了同一个方法 - 静态方法没有多态
-
参数静态绑定,接收者动态绑定 => 多态只对方法的接收者有效 => 多态只选择接收者的类型,不选择参数的类型
class Main { public static void main(String[] args) { Base object = new Sub(); ParamsBase params = new ParamsSub(); // 方法的接收者 object object.print(params); // I Sub, the param is ParamsBase. object.print((ParamsSub) params); // I Sub, the param is ParamSub. } } class Base { public void print(ParamsBase param) { System.out.println("I am Base, the param is ParamsBase."); } public void print(ParamsSub param) { System.out.println("I am Base, the param is ParamSub."); } } class Sub extends Base { @Override public void print(ParamsBase param) { System.out.println("I Sub, the param is ParamsBase."); } @Override public void print(ParamsSub param) { System.out.println("I Sub, the param is ParamSub."); } } class ParamsBase { } class ParamsSub extends ParamsBase { }
- 方法调用的时候由类实际的对象决定如何响应这个抽象的方法
策略模式体现多态
class User {
private boolean vip;
public boolean isVip() {
return vip;
}
}
class PriceCalculator {
public int calculate(DiscountStrategy discountStrategy, int price, User user) throws IllegalAccessException {
// 每次新增一种策略就要多加一个类
return discountStrategy.discount(price, user);
// switch (strategy) {
// case "NoDiscount":
// return price;
// case "95":
// return (int) (price * 0.95);
// case "VIP":
// if (user.isVip()) {
// return (int) (price * 0.85);
// }
// return (int) (price * 0.95);
// // ...
// default:
// throw new IllegalAccessException();
// }
}
}
class DiscountStrategy {
public int discount(int price, User user) {
return price;
}
}
class NoDiscountStrategy extends DiscountStrategy {
@Override
public int discount(int price, User user) {
return price;
}
}
class Discount95Strategy extends DiscountStrategy {
@Override
public int discount(int price, User user) {
return (int) (price * 0.95);
}
}
class VipDiscountStrategy extends DiscountStrategy {
@Override
public int discount(int price, User user) {
if (user.isVip()) {
return (int) (price * 0.85);
}
return (int) (price * 0.95);
}
}
// java.util.concurrent.RejectedExecutionHandler
public interface RejectedExecutionHandler {
}
public static class AbortPolicy implements RejectedExecutionHandler {
}
public static class CallerRunsPolicy implements RejectedExecutionHandler {
}
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
}
public static class DiscardPolicy implements RejectedExecutionHandler {
}
组合
public class Main {
class Driver {
void drive() {
// 100 行复杂代码
}
void fixCar() {
// 50 行复杂代码
}
}
class Doctor {
void fixPatient() {
// 30 行复杂代码
}
}
// 组合 Driver & Doctor
class DoctorDriver {
Driver driver;
Doctor doctor;
void driver() {
driver.drive();
}
void fixCar() {
driver.fixCar();
}
void fixPatient() {
doctor.fixPatient();
}
}
}
继承 vs 组合
- 继承 => is-a
- 组合 => has-a
网友评论