TimurVI Asked:2020-12-27 19:53:00 +0000 UTC2020-12-27 19:53:00 +0000 UTC 2020-12-27 19:53:00 +0000 UTC 单根类层次结构有什么好处? 772 例如,当所有类都继承自一个类时,单个根类层次结构的主要优点是什么Object?是什么促使具有单一根类层次结构的语言的开发者走上这条路? ооп 5 个回答 Voted Best Answer Vadim Ovchinnikov 2020-01-08T16:09:11Z2020-01-08T16:09:11Z 主要是为了让所有的对象和类都有一个共同的行为,以及一个包含在虚方法中可以被覆盖的默认行为。单个根对象最适合于此。这确保所有类型都具有已定义的方法。 为了能够编写可以对完全不同的类型以不同方式工作的成员(方法、属性、索引器、事件等)。然而,这个特性被更方便的 Generic 大大提升了水平,并且消除了类型检查和转换的需要,在运行时可以看到其中的错误。但是,仍然有一个 API(包括标准 API)是在 Generic 之前开发的,它大量使用了根类型。 Алексей Шиманский 2020-01-08T16:15:13Z2020-01-08T16:15:13Z 我不知道有什么好处,但在我看来,确定后代类可以拥有的公共部分有时是很合乎逻辑的(有时是因为你不需要把它到处乱推乱放) . 有时会发现,在分析和构建未来的结构(层次结构)时,会发现所有类都会有一些共同的字段、方法(当然,构建层次结构的过程用不了一天,有时甚至一个月都不到。这个一定要记住)。所以在C#和Java中有一个方法toString返回一个对象的字符串表示Finalize——你可以在其中描述对象被销毁时的逻辑和其他字段/方法。在许多其他类中一直描述这些方法是没有意义的。这至少是多余的。 这在某种程度上更自然,打个比方:有些人相信人类是亚当和夏娃的后裔。这是一种相同的层次结构和从根继承))这样的层次结构也更容易理解:一棵树只从上到下生长,有共同的根,从一个来源取食,而不是像种植灌木一样,旋花杂草,在它后面你看不到你的花园和你的西红柿和黄瓜。 m. vokhm 2020-12-30T16:42:38Z2020-12-30T16:42:38Z 多重继承提供了额外的灵活性和代码可重用性,但引入了许多与歧义相关的问题,当我们类的两个或多个祖先具有具有相同签名的方法时,就会发生歧义。最著名的问题是所谓的。“钻石问题”,当我们同时继承两个类(例如,我们称它们为 A 和 B)时,这两个类是它们的同一个共同祖先的后代,并且我们的两个祖先中的每一个都覆盖共同祖先中定义的方法,比如int common(int i). 当使用我们类的代码调用它的方法common(33)时,应该执行哪个方法——A.common() 或 B.common()? 不同的实现多重继承的语言解决问题的方式不同,但无论如何,这些解决方案导致了语言的复杂化,有时会出现人为的限制等。 在实际项目中,使用的类层次结构通常非常复杂和混乱(只要看看任何普通语言的标准类库),这些情况下的多重继承问题会变成很多令人头疼的问题,从而产生很多错误不容易找到和修复。 此外,多重继承通常会促使程序员使用导致错误出现的混乱和模棱两可的解决方案,与单继承相比,单继承通常提供更大的逻辑清晰度和解决方案的连贯性,因此降低了出现错误的可能性错误。 因此,许多程序员(包括 Java 的创造者)得出了纯粹的多重继承比灵活性带来更多痛苦和头痛的结论,并放弃了它。并且通过其他方式非常成功地实现了所需的灵活性——接口、通用类等。 请参阅https://ru.wikipedia.org/wiki/Diamond-shaped_inheritance,嗯,一般来说,您可以搜索他们写的地方 - 例如。http://www.viva64.com/ru/b/0204/ Mikhail Vaysman 2020-12-27T23:01:29Z2020-12-27T23:01:29Z 例如,Java 使用“简单”(不是多重)继承,如果没有层次结构的单个根,将很难(不可能)组织容器 - 列表、映射等。 这种层次结构是在 Smalltalk 中引入的,许多语言都借鉴了它的思想。 在我看来,这样的组织更容易理解,并且减少了开发中的错误数量。 Harry 2020-01-12T19:20:49Z2020-01-12T19:20:49Z 我的恕我直言,仅此而已——这在某种程度上是泛型编程的替代品。比如在C++的STL之前,我个人就想写一个像current vector这样的容器类。这并不难,就我的目的而言,它已经完成了——但有必要指定一个特定的类型。因此,有两种选择——要么重写每种类型的代码,要么从一些常见的类中生成我想隐藏在容器中的所有类(在这种情况下,基本类型在范围内)。模板非常优雅地解决了这个问题。 就我对 Java 的了解,他们最初走了一条不同的路,而泛型已经是一个完全不同时代的机会。相同(如果我错了,请纠正),即使是基本类型,原则上也是类。一些其他设计决策提供了 C++ 泛型编程的替代品,并且在语言本身中得到积极使用——例如,用于相同的转换,到字符串。
主要是为了让所有的对象和类都有一个共同的行为,以及一个包含在虚方法中可以被覆盖的默认行为。单个根对象最适合于此。这确保所有类型都具有已定义的方法。
为了能够编写可以对完全不同的类型以不同方式工作的成员(方法、属性、索引器、事件等)。然而,这个特性被更方便的 Generic 大大提升了水平,并且消除了类型检查和转换的需要,在运行时可以看到其中的错误。但是,仍然有一个 API(包括标准 API)是在 Generic 之前开发的,它大量使用了根类型。
我不知道有什么好处,但在我看来,确定后代类可以拥有的公共部分有时是很合乎逻辑的(有时是因为你不需要把它到处乱推乱放) . 有时会发现,在分析和构建未来的结构(层次结构)时,会发现所有类都会有一些共同的字段、方法(当然,构建层次结构的过程用不了一天,有时甚至一个月都不到。这个一定要记住)。所以在C#和Java中有一个方法
toString返回一个对象的字符串表示Finalize——你可以在其中描述对象被销毁时的逻辑和其他字段/方法。在许多其他类中一直描述这些方法是没有意义的。这至少是多余的。这在某种程度上更自然,打个比方:有些人相信人类是亚当和夏娃的后裔。这是一种相同的层次结构和从根继承))这样的层次结构也更容易理解:一棵树只从上到下生长,有共同的根,从一个来源取食,而不是像种植灌木一样,旋花杂草,在它后面你看不到你的花园和你的西红柿和黄瓜。
多重继承提供了额外的灵活性和代码可重用性,但引入了许多与歧义相关的问题,当我们类的两个或多个祖先具有具有相同签名的方法时,就会发生歧义。最著名的问题是所谓的。“钻石问题”,当我们同时继承两个类(例如,我们称它们为 A 和 B)时,这两个类是它们的同一个共同祖先的后代,并且我们的两个祖先中的每一个都覆盖共同祖先中定义的方法,比如
int common(int i). 当使用我们类的代码调用它的方法common(33)时,应该执行哪个方法——A.common() 或 B.common()?不同的实现多重继承的语言解决问题的方式不同,但无论如何,这些解决方案导致了语言的复杂化,有时会出现人为的限制等。
在实际项目中,使用的类层次结构通常非常复杂和混乱(只要看看任何普通语言的标准类库),这些情况下的多重继承问题会变成很多令人头疼的问题,从而产生很多错误不容易找到和修复。
此外,多重继承通常会促使程序员使用导致错误出现的混乱和模棱两可的解决方案,与单继承相比,单继承通常提供更大的逻辑清晰度和解决方案的连贯性,因此降低了出现错误的可能性错误。
因此,许多程序员(包括 Java 的创造者)得出了纯粹的多重继承比灵活性带来更多痛苦和头痛的结论,并放弃了它。并且通过其他方式非常成功地实现了所需的灵活性——接口、通用类等。
请参阅https://ru.wikipedia.org/wiki/Diamond-shaped_inheritance,嗯,一般来说,您可以搜索他们写的地方 - 例如。http://www.viva64.com/ru/b/0204/
例如,Java 使用“简单”(不是多重)继承,如果没有层次结构的单个根,将很难(不可能)组织容器 - 列表、映射等。
这种层次结构是在 Smalltalk 中引入的,许多语言都借鉴了它的思想。
在我看来,这样的组织更容易理解,并且减少了开发中的错误数量。
我的恕我直言,仅此而已——这在某种程度上是泛型编程的替代品。比如在C++的STL之前,我个人就想写一个像current vector这样的容器类。这并不难,就我的目的而言,它已经完成了——但有必要指定一个特定的类型。因此,有两种选择——要么重写每种类型的代码,要么从一些常见的类中生成我想隐藏在容器中的所有类(在这种情况下,基本类型在范围内)。模板非常优雅地解决了这个问题。
就我对 Java 的了解,他们最初走了一条不同的路,而泛型已经是一个完全不同时代的机会。相同(如果我错了,请纠正),即使是基本类型,原则上也是类。一些其他设计决策提供了 C++ 泛型编程的替代品,并且在语言本身中得到积极使用——例如,用于相同的转换,到字符串。