04:当谈论面向对象的时候,我们到底在谈什么? 面向对象有两个非常重要和基础的概念,就是类和对象。 以类和对象作为组织代码的基本单元。 四大特性:封装、继承、多态、抽象。 面向对象分析和设计:最后的产出是类,围绕对象和类来展开分析和设计。 05:封装、抽象、继承、多态分别可以解决哪些编程问题? 1:封装 也叫数据访问保护。仅开放有限的接口。 需要“访问权限控制”的语法机制支持。类比于冰箱而言就是功能按钮不要弄太多。 2:抽象 隐藏方法的具体实现。通过函数来实现。 人类处理复杂问题的通用有效手段。 很多原则提现了抽象的特点。“基于接口而非实现编程”、开闭原则、代码解耦等。 3:继承 标示类之间的is-a关系。 继承的最大好处就是代码复用。通过抽象父类,子类继承父类可以避免代码写多遍。 过度使用继承,代码可读性变差。原则:“多用组合,少用继承。” 4:多态 多态是指,子类可以替换父类。 多态实现方式: 1:继承+方法重写 2:接口类<Iterator/Array/LinkedList/Map> 3:duck-typing(python/JS)<只要两个类具有相同的方法,就可以实现多态> 多态也是很多设计原则、设计模式、编程技巧的代码实现基础。比如策略模式、“基于接口而非实现编程”、依赖倒置原则、里式替换原则。利用多态去除冗长的if-else 06:面向对象相比面向过程有哪些优势?面向过程真的过时了吗? 1:什么是面向对象语言?什么是面向过程语言? 面向对象语言:以类和对象为组织代码的基本单元。具有封装、继承、多态、抽象的特征。 面向过程语言:以过程(函数)作为组织代码的基本单元。 2:面向对象编程有哪些优势? 1:应对大规模复杂程序 2:易复用、易扩展、易维护(基于四大特性的优势) 3:更高级(语言进化的历程,更贴近人类) 07:哪些代码设计看似是面向对象,实际是面向过程的? 1:滥用getter、setter方法 除非真的需要,否则尽量不要给属性定义setter方法。如果getter返回的是集合容器,需要防范内部数据被修改。 2:滥用全局变量和全局方法 全局变量:1.拆解成多个功能单一的类;2.将常量定义在类中。 全局方法:避免滥用、功能细化。 3:定义数据和方法分离的类(“贫血模型”) 08:接口vs抽象类的区别?如何用普通的类抽象类和接口? 1:抽象类:(is-a) 1:抽象类不允许实例化,只能被继承。 2:抽象类包含属性和方法,方法可以实现也可以不实现。 3:子类继承抽象类,必须实现父类所有的方法。 2:接口:(has-a) 1:接口不能包含属性。 2:接口只能声明方法,方法不能包含代码实现。 3:类实现接口的时候,必须实现接口所有的方法。 3:为什么需要抽象类?(is-a) 抽象类就是为代码复用而生的。 4:为什么需要接口?(has-a) 抽象类侧重于代码复用。接口侧重于解耦。 接口是一个比抽象类更加广泛、更加重要的知识点。 “基于接口而非实现编程”,提高代码的灵活性、扩展性。 5:如何模拟抽象类、接口的概念? 1:用抽象类模拟接口。 2:用普通类模拟接口。 3:用普通类模拟抽象类。 09:为什么“基于接口而非实现编程”?有必要为每个类都定义接口吗? 1:如何理解原则中的“接口”二字? Program to an interface ,not an implementation。 接口是一组“协议”或者“约定”。 2:具体方法 1:函数命名不能暴露细节。 2:封装具体的实现细节。 3:为实现类定抽象的接口。 总结一下,编码时一定要有:抽象意识、封装意识、接口意识。 3:是否需要为每个类定义接口? 根据系统变更的概率性来评估。 10:为何说要多用组合少用继承?如何决定该用组合还是继承? 1:继承层次过深、继承关系过于复杂会影响到代码的可读性和可维护性。 鸟类(飞、叫、下蛋),3个维度如何定义父类? 2:组合相对继承有哪些优势? 通过组合、接口、委托三个技术手段,可以替代继承。 鸟类(是否会飞、是否会叫、是否会下蛋)自由选择实现接口。 3:如何判断该用组合还是继承? 继承:系统稳定、继承层次浅 组合:系统不稳定、继承层次深 4:一些设计模式会固定使用继承或者组合。 1:组合关系:装饰者模式、策略模式、组合模式 2:继承关系:模板模式