文章目录
05 | 理论二:封装、抽象、继承、多态分别可以解决哪些编程问题?
1. 封装(Encapsulation): 如何隐藏信息、保护数据
- 类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(或者叫函数)来访问内部信息或者数据。
- 封装通过 访问权限控制 机制来支持的,即private、public等关键字控制。
- 意义:
1.增加可维护性:防止因不了解业务逻辑而进行一些重要数据的修改。
2.提高类的易用性:如果我们把类属性都暴露给类的调用者,调用者想要正确地操作这些属性,就势必要对业务细节有足够的了解。而这对于调用者来说也是一种负担。
2. 抽象(Abstraction): 隐藏方法的具体实现
- 实现抽象特性:接口类、抽象类
- 意义:
1.过滤一些非关键性的细节
2.抽象是一个非常宽泛的设计思想,在代码设计中气到非常重要的指导作用。
3. 继承(Inheritance)
- 继承用来表示类之间的 is-a 关系,如猫是哺乳动物。
- 分为单继承或者是多继承,单继承表示一个子类只继承一个父类,多继承表示一个子类可以继承多个父类,比如猫既是哺乳动物,又是爬行动物。
- 不过,有些编程语言只支持单继承,不支持多重继承,比如 Java、PHP、C#、Ruby 等,而有些编程语言既支持单重继承,也支持多重继承,比如C++、Python、Perl 等。
- 意义:代码复用
4. 多态(Polymorphism)
-
多态:子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。
-
实现方法:
- 继承加方法重写
- 利用接口类语法
- 利用 duck-typing 语法(只要两个类具有相同的方法,就可以实现多态)
-
实现方法之继承加方法重写:
public class DynamicArray { public void add(Integer e) {} } public class SortedDynamicArray extends DynamicArray { @Override public void add(Integer e) {} } public static void main(String args[]) { DynamicArray dynamicArray = new SortedDynamicArray(); }
-
实现方法之利用接口类语法实现多态
public interface Iterator {} public class Array implements Iterator {} public class LinkedList implements Iterator {} public static void main(String[] args) { Iterator arrayIterator = new Array(); Iterator linkedListIterator = new LinkedList(); }
-
实现方法之利用duck-typing 来实现多态
class Logger: def record(self): print(“I write a log into file.”) class DB: def record(self): print(“I insert data into db. ”) def test(recorder): recorder.record() def demo(): logger = Logger() db = DB() test(logger) test(db)
Logger 和 DB 两个类没有任何关系,既不是继承关系,也不是接口和实现的关系,但是只要它们都有定义了record() 方法,就可以被传递到 test() 方法中,在实际运行的时候,执行对应的 record()
方法。 -
意义:
- 能提高代码的可扩展性和复用性
- 是很多设计模式、设计原则、编程技巧的代码实现基础
5. 课堂讨论
-
你熟悉的编程语言是否支持多重继承?如果不支持,请说一下为什么不支持。
- Java 不支持多重继承。
- 多重继承有副作用:钻石问题(菱形继承)。
假设类 B 和类 C 继承自类 A,且都重写了类 A 中的同一个方法,而类 D 同时继承了类 B
和类 C,那么此时类 D 会继承 B、C 的方法,那对于 B、C 重写的 A 中的方法,类 D 会继
承哪一个呢?这里就会产生歧义。
-
你熟悉的编程语言对于四大特性是否都有现成的语法支持?对于支持的特性,是通过什
么语法机制实现的?对于不支持的特性,又是基于什么原因做的取舍?