OOP的学校是什么?

Ara*_*raK 30 c# c++ java oop

Smalltalk OOP和Simula OOP之间是否存在哲学差异?

这是一个间接与Java&C#vs C++相关的问题.据我所知,C++基于Simula,但Java和C#或多或少来自Smalltalk系列.

Shu*_*oUk 64

在更广泛的OOP旗帜中,'Style'的几个关键'差异'.

在所有情况下,关于静态动态类型系统的陈述主要是指一个或另一个,问题远非明确或明确定义.此外,许多语言选择模糊选项之间的界限,因此这不是任何方式的二元选择列表.

多态晚期结合

或"什么foo.Bar(x)意思?"

  1. 类型的层次结构被扁平化为每个实例的特定实现(通常通过vtable完成),并且通常允许显式引用基类实现.
    • 从概念上讲,你看一下foo在callsite上最具体的类型.如果它有一个被调用的参数x的Bar实现,如果不是,则选择foo的父级并重复该过程.
    • 示例:C++/Java/C#,经常使用" Simula样式 ".
  2. 纯粹的消息传递.foo中处理消息'named'"Bar"的代码被要求接受x.只有名称很重要,而不是呼叫网站可能对Bar究竟是什么意味着什么假设.与之前的样式相比,其中所讨论的方法是Bar,已知在编译时定义的类型层次结构上已知的内容(尽管层次结构中的精确位置保留到运行时).

1通常在静态类型框架中使用,在这种框架中它是一个错误,在编译时检查是否存在这样的实现.此外,如果x和y是不同类型,则语言通常区分Bar(x)和Bar(y).这是方法重载,并且具有相同名称的结果方法被视为完全不同.

2通常用在动态语言中(这往往会避免方法重载),因为在运行时foo的类型对于名为"Bar"的消息没有"处理程序",不同的语言可能以不同的方式处理它.

如果需要,两者都可以在幕后以相同的方式实现(通常,第二种,Smalltalk样式的默认设置是调用一个函数,但在所有情况下都没有定义的行为).由于前一种方法可以经常容易地实现为简单的指针偏移函数调用,因此可以更容易地使其相对快速地进行.这并不意味着其他样式也不能快速制作,但可能需要做更多工作以确保在这样做时不会损害更大的灵活性.

继承/重用

或"婴儿从何而来?"

  1. 基于类
    • 方法实现被组织成称为类的组.当需要实现继承时,定义一个扩展父类的类.通过这种方式,它可以获得父级的所有暴露方面(包括字段和方法),并且可以选择更改某些/所有方面,但不能删除任何方面.您可以添加和更新但不能删除.
    • 示例:C++/Java/C#(注意SmallTalk和Simula都使用此方法)
  2. 基于原型
    • 对象的任何实例都只是已识别方法的集合(通常由名称标识)和以(再次命名)字段的形式的状态.每当需要此"类型"的新实例时,可以使用现有实例来克隆新实例.此新类保留上一个类的状态和方法的副本,但可以进行修改以删除,添加或更改现有的命名字段和方法.
    • 示例:自我/ JavaScript

同样,1倾向于在静态语言中发生,2在动态中发生,尽管这绝不是一个要求,它们只是适合于风格.

基于接口或类

或"什么或如何?"

  1. 接口列出了所需的方法.他们是合同
    • 示例:VB6
  2. 类列出了所需的方法,但可以选择提供它们的实现
    • 示例:Simula

这绝不是二元选择.大多数基于类的语言都允许抽象方法的概念(尚未实现的方法).如果你有一个所有方法都是抽象的类(在C++中称为纯虚拟),那么这个类相当于一个接口,尽管它可能也定义了一些状态(字段).一个真正的接口应该没有状态(因为它定义什么是可能的,它不是如何发生的.

只有较旧的OOP语言往往只依赖于其中一种语言.
VB6只在接口上,没有实现继承.
Simula允许您声明纯虚拟类,但您可以实例化它们(使用时出现运行时错误)

单个或多个继承

或者"谁是爸爸?"

    • 只有一种类型可以是另一种类型的父类型.在上面基于类的表单中,您可以只扩展(从中获取实现)一种类型.通常,这种形式包括接口的概念作为语言的第一类方面来弥补这一点.
    • 优点包括更清晰的元数据和内省,更简单的语言规则.
    • 并发症包括使得将有用的方法纳入范围变得更加困难(诸如MixInsExtension方法之类的东西试图缓解这类问题)
    • 示例:C#/ java
  1. 多个 - 您可以扩展多个类
    • 优点包括某些结构更易于建模和设计
    • 复杂性包括复杂的冲突解决规则,尤其是当存在可能采用父类型的重载方法时.
    • 示例:C++/Eiffel

这个问题引起了相当大的争论,特别是因为它是C++的OOP实现和许多现代静态类型语言之间的关键区别,这些语言被认为是可能的继承者,如c#和java.

可变性

或者"你想对我做什么?"

  1. 易变的
    • 对象一旦创建就可以更改其状态.
  2. Imutable
    • 对象一旦创建就无法更改.

通常这不是全部或全部,它只是一个默认值(默认情况下,最常用的OOP语言默认为可变).这会对语言的结构产生很大的影响.许多主要包含OOP功能的函数式语言都默认对象具有不可变状态.

他们的OOP'纯粹'

或者"一切都是对象吗?"

  1. 绝对地,系统中的所有东西都被视为一个对象(甚至可能只是方法本身,它只是另一种对象,可以与其他对象相同的方式进行交互).
    • 示例:SmallTalk
  2. 不是所有东西都是一个对象,你不能将消息传递给所有东西(虽然系统可能会跳过箍,使它看起来像你可以)
    • 示例:C++/C#/ Java(参见注释*)

这是非常复杂的,因为像原始的自动装箱这样的技术使它看起来像一切都是但你会发现存在这样的"编译器魔法"并且在幕后发现Oz的众所周知的向导导致问题或错误的几个边界情况.在具有不变性作为默认值的语言中,这种情况不太可能发生,因为对象的关键方面(它们包含方法和状态)意味着与对象类似但不太可能出现并发症的事物.

  • 关于Java/C#,自动装箱(或在c#中)系统允许你在语法上处理任何变量,好像它是一个对象,但实际上情况并非如此,这在诸如试图锁定自动装箱的区域中展示对象(由编译器拒绝,因为它将是一个明显的错误).

静态或动态

或者"你认为你是谁?"

语言设计的一个更普遍的方面,而不是一个进入这里,但这个决定固有的选择影响了前面提到的OOP的许多方面.

多态晚期绑定的各个方面可以取决于:

  • 消息传递给的对象的类型(在编译时/运行时)
  • 的类型的参数(的小号,其被传递)(在编译时间/运行时间)

语言变得越动态,这些决策往往变得越复杂,但相反,语言用户的输入越多,而不是语言设计者在决策中的输入.这里给出的例子可能是一些愚蠢的东西,因为静态类型语言可能被修改为包含动态方面(如c#4.0).

  • 现在这就是我所说的答案! (10认同)
  • 我最大的抱怨 - 继承的副标题应该是"babby是如何形成的?" (9认同)
  • :)我背叛了我的英语 (2认同)

APr*_*mer 6

我也把Java和C#放在Simula阵营:

  • Smalltalk是动态类型的,与你引用的其他四种语言完全不同.

  • Smalltalk是结构类型(别名鸭子打字),而其他四个名义上打字.

(Java和C#与Smalltalk的共同点主要是基于VM,但对编程风格的影响很小).