Life is like a Markov chain,
         your future only depends on what you are doing now,
                               and independent of your past.

松本行弘的程序世界 笔记 (一)

单一继承的特点是单纯的树结构,继承关系单纯。

 

多重继承有以下两个优点:

  • 很自然地做到了单一继承的扩展;
  • 可以继承多个类的功能。

 

多重继承会导致下列 3 个问题。

  • 结构复杂化
  • 优先顺序模糊
  • 功能冲突

 

因为多重继承有多个父类,所以当不同父类中有相同的方法时就会产生冲突。

 

从大的方面来看,编程语言可以分为静态语言和动态语言两种。

 

静态语言中,不能给变量赋不同类型的值,因为那样会导致编译错误。不通过执行就可以发现类型不匹配这样的错误是静态语言的一个优点。静态类型面向对象编程语言被设计成这样,当给一个类变量赋值时,既可以用这个类的对象来赋值,也可以用这个类的子类对象来赋值。这样就可以实现多态性。

 

动态语言允许调用没有继承关系的方法。

 

在静态语言中,如果要调用类层次中平行类的方法,那么必须要有一个可以表现这些对象的类型。如果没有这个类型,可调用的方法是非常有限的。

只有包含继承关系的类才会具有多态性。

继承包含两种含义。一种是"类都有哪些方法",也就是说这个类都支持些什么操作,即规格的继承。另外一种是,"类中都用了什么数据结构和什么算法",也就是实现的继承。

 

类是用来指定对象实现的,而接口只是指定对象的外观(都有哪些方法)。

 

Mix-in 技术按照以下规则来限制多重继承。

  • 通常的继承用单一继承, 第二个以及两个以上的父类必须是 Mix-in 的抽象类 Mix-in 类是具有以下特征的抽象类。
  • 不能单独生成实例
  • 不能继承普通类

 

现在对面向对象最好的理解是,面向对象编程是结构化编程的延伸。

 

结构化编程基本上实现了控制流程的结构化。但是程序流程虽然结构化了,要处理的数据却并没有被结构化。面向对象的设计方法是在结构化编程对控制流程实现了结构化后,又加上了对数据的结构化。

 

面向对象编程语言中的对象,像字符串、数组和范围等,很多都没有现实世界中的具体物体与之对应。即使现实世界中有具体物体与之对应,对象也只是描述现实物体某一侧面的抽象概念而已。

 

无论哪种面向对象编程语言都具有以下的共通功能。

  • 不需要知道内部的详细处理就可以进行操作(封装、数据抽象)。
  • 根据不同的数据类型自动选择适当的方法(多态性)。

 

类是对象的模板,相当于对象的雏形。通过类可以把同一类的对象管理起来。

 

避免重复的方法是继承。

 

类是模块,继承就是利用模块的方法。

 

子类对象拥有父类所有属性,可以当做父类对象来处理,这种状态称为 LSP(Liscov Substitution Principle)。

 

实现的共享可以通过多个对象的组合(composition)和委托(delegate)来做到,组合是把多个对象合成一个对象来处理。委托是把对一个对象的方法调用委派给别的对象。

 

用 Mix-in 做多重继承设计时,从第 2 个父类开始的类要满足以下条件。

  • 不能单独生成实例的抽象类。
  • 不能继承 Mix-in 以外的类。

多重继承编程语言都有自己的对应方法,大致上分为以下 3 种。

  • 给父类定义优先级 重复的时候使用优先级高的父类属性。Common Lisp Object System(CLOS)提供的这个功能在继承数据类型时很有效。
  • 把重复的名字替换掉 Eiffel 使用的就是这种方法。在模块继承时用这种方法很有效,其缺点是写程序时很复杂。
  • 指定使用类的名字 C++用的是这种方法。这也是在继承模块时有效的方法。缺点是本来不需要指定类名的情况现在却要指定。

 

多重继承并不可怕。今后面向对象编程语言必须有某种形式的多重继承。

 

类既有类型的一面又有模块的一面。

 

使用 Mix-in 可以避免多重继承的类关系变复杂。

 

静态是指程序执行之前,从代码中就可以知道一切。程序静态的部分包括变量、方法的名称和类型以及控制程序的结构等等。

 

动态是指在程序执行之前有些地方是不知道的。程序动态的部分包括变量的值、执行时间和使用的内存等等。

 

编程语言中的类型指的是数据的种类。

 

静态类型最大的优点是在编译时能够发现类型不匹配的错误。

 

如果明确指定了数据类型,那么编译时可以用到的信息就很多。数据类型信息不只是对编译器有用。我们在看程序的时候,"这个参数是什么类型"的信息对我们理解程序也是有很大帮助的。

 

动态类型编程语言的最大优点是源代码变得很简洁。同样的处理,在大多数情况下,静态类型编程语言运行得要快些。这是因为动态类型程序执行时要做类型检查。另外,静态类型的编程语言大都通过编译把程序源代码转换成可以直接执行的形式,而动态类型的编程语言大多是边解释源代码(转换成内部形式)边执行,这种编译型处理和解释型处理的区别也是影响程序执行速度的原因之一。

 

动态类型编程语言的另外一个特点是灵活性。动态类型语言的程序不用指定变量的数据类型。

 

动态类型编程语言的最大缺点是不执行就检测不出错误。

 

If it walks like a duck and quacks like a duck, it must be a duck(走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子)。

 

使用静态类型语言,程序员通过类型定义提供了大量的信息,错误可以尽早检测出来,程序确保可以执行。其代价是,如果类型设计的前提发生了变化,为保证各种类型的一致性,所有关联的部分都要修改。动态类型语言因为开始就不需要定义数据类型,所以适应类型变化的能力比较强。

 

Duck Typing 的概念设计时要遵循什么原则呢?

  • 避免明确的类型检查
  • 无论如何都想检查的时候,也不要检查对象是否属于某个类,而是要检查对象是否有某个方法

 

动态类型的缺点

  • 在执行时才能发现错误
  • 读程序时可用到的线索少
  • 运行速度慢

 

执行时才能发现错误这一点可以用完备的单元测试来解决。

 

读程序时可用到的线索少这一点可以通过完整的文档来解决。

 

运行速度慢这一点,随着计算机性能的提高已经不再重要,现在的程序开发中,程序的灵活性和生产力更为重要。

 

我们对程序开发生产力的要求越来越高,要在更短的时间内开发出更多的功能。

 

"元"一词来源于希腊语中表示"……之间,……之后,超越……"的前缀"meta",有"超越"和"高阶"等意思。

 

元编程是对程序进行编程的意思。

 

编程的反射(reflection)功能——在编程语言中它是指在程序执行时取出程序的信息或者改变程序信息。

 

我们可以给这个对象增加特异方法来改变它的部分行为,这就大大扩展了它的应用范围。

所谓特异方法,是指类中没有定义而只存在于实例(对象)中的方法。用别的类对象来循环处理容器中的元素,这种循环处理的方式称为外部迭代器方式。在外部迭代器方式中,把顺序取出容器中元素的对象称为迭代器,也称为游标。

 

设计模式来看,内部迭代器是访问者模式,外部迭代器是迭代器模式。

posted @ 2018-03-14 22:06  Hu_Yan  阅读(123)  评论(0编辑  收藏  举报