是否有没有继承的OO语言?


22

在今天的代码审查中,我的一位同事说了一些有趣的事情:

prototype仅在需要继承时才有用- 何时继承是个好主意

我考虑了一下,然后意识到,我通常使用继承来解决最初设计不好的代码。现代的OO风格更喜欢使用组合而不是继承,但是我不知道有哪一种语言能够真正做到这一点并真正执行它。

是否有带有类,对象,方法,接口等的通用编程语言,这些语言不允许基于类的继承?(如果这样的想法没有意义,为什么不呢?)


7
您的同事使您误入歧途。该prototype也是当你有公共的方法和应该实例之间共享性质是有用的。这也很有用,因为它允许您instanceof在JavaScript:中正确使用运算符if (foo instanceof Foo) { ...
格雷格·伯格哈特

2
我认为我们应该区分类型,状态和行为的继承。组合的偏爱在Java社区中很常见,但与此同时,类型的继承(甚至多重继承)被广泛使用和鼓励...并使用implements关键字和接口来实现(与状态和状态的继承相对)extends在包含任何实现的类上使用关键字引入的行为)。
toniedzwiedz 2014年

6
首选组合并不意味着完全放弃继承是一个好主意。
Caleb 2014年

5
看到没有实现继承的Java:“ Google的发展是一种语言的示例,该语言在实现面向对象编程的同时就消除了实现继承……”
t 2014年

1
@GregBurghardt可以通过工厂函数来完成相同的操作,该函数返回一个包含函数的对象(在闭包中存储私有数据)。newthis而且prototype对于IMO而言都是太多的雷区。
本杰明·霍奇森

Answers:


18

抛开面向对象程序设计的定义问题,问题变成了“是否存在仅使用组合并且没有继承工具的语言?”之一。

答案很简单,就是“是”。在进行中,没有一种方法可以像传统上那样进行继承。一个可以嵌入在另一对象的对象和延伸该对象。从面向对象的语言github镜像):

type Person struct {
        Name string
}

func (p *Person) Intro() string {
        return p.Name
}

type Woman struct {
        Person
}

func (w *Woman) Intro() string {
        return "Mrs. " + w.Person.Intro()
}

您具有名称为String的人员结构。它具有一个称为Intro的公共函数,该函数返回名称。Woman结构体还具有Intro函数,该函数可访问嵌入在其中的支杆。因此,仅使用组合就可以实现继承的意图。

有关更多信息,请参见GoLang教程:Go-或类似的继承和子类化

所以是的,有一种没有继承的OO语言是可能的,并且确实存在。

在内部,这被称为嵌入,它使封闭结构能够访问嵌入的字段和函数,就好像它也具有它们一样-但这不是子类。可以在Go FAQ中找到设计原理:为什么没有类型继承?


人们还可以对使用的意见typedef,并struct用C ...
cwallenpoole

@cwallenpoole确实有类似的想法,尽管我会毫不犹豫地将C称为面向对象的语言。

我不知道。我承认一个事实,那就是您无法创建带有附加功能的对象,但确实存在问题,但是如果没有继承,OOP就会失去其大部分功能。
cwallenpoole 2014年

@cwallenpoole,我们开始定义什么是继承和面向对象。但是可能,这只是对问题的另一种思考方式。事实是,继承是大多数C ++和Java程序员认为扩展的方式...但是还有其他模型。无继承扩展:123是好读。

目前,“面向对象的语言”的链接仍停留在重定向循环中,但是我在这里找到了这篇文章:github.com/nu7hatch/areyoufuckingcoding.me/blob/master/content/…。谢谢!
马特·布朗

7

是否有带有类,对象,方法,接口等的通用编程语言,这些语言不允许基于类的继承?

这读起来很像VBA的描述,它是嵌入在Microsoft Office和其他启用VBA的主机(例如AutoCAD,Sage 300 ERP等)甚至VB6中的VBA-应用程序的Visual Basic。无论如何,“基本”的“ A”代表“通用”,因此存在“通用”部分。

VB6 / VBA具有类(以及对象),方法和接口-您可以ISomething在类模块中定义一个接口,如下所示:

Option Explicit

Public Sub DoSomething()
End Sub

然后有另一个类可以做到这一点:

Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
    'implementation here
End Sub

这样的类,不公开成员,只能通过其ISomething接口访问-而且很可能会有数十种不同的实现ISomething,因此OOP VBA代码完全可以实现多态,并且对于给定的类来说是完全合法的也可以实现多个接口。

但是,VB6 / VBA不允许类继承,因此您不能从其他类型继承实现,只能从其接口继承。现在,这是意外,设计缺陷,天才之举还是巨大的丑陋监督,都值得商debate。尚不清楚VB6 / VBA是否会牢记这一点,但绝对可以执行

如果Go不进行类继承并且仍然是OOP语言,那么我不明白为什么VB6 / VBA也不能被视为OOP语言。</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>


1
公平地说,OP询问了现代语言。=;)-–
RubberDuck

@RubberDuck#烧伤!
Mathieu Guindon

0

您可以使编译器通过使用private / protected以及现代使用的“ PImpl”或“ Private Implementation”技术来强制执行选择性继承。

许多API仅公开您希望用户继承的那些组件,并将其余组件隐藏在单独的实现类中。因此,您可以编写其公共接口实际上是不可继承的类,仅可通过对象组合使用并由编译器强制使用。当它使用编译器强制执行软件的意图时,这通常是一种好习惯。

快速搜索javascript中的私有成员函数显示出一个相似的原理,尽管任何人都可以使用它查看您的代码:http : //www.crockford.com/javascript/private.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.