草庐IT

java - 在接口(interface)中添加默认和静态方法的原因

coder 2024-03-11 原文

Java 8 在接口(interface)上引入了默认方法和静态方法。所以现在无论是使用默认方法还是静态方法,您都可以在接口(interface)中拥有具体的实现。

Java 声称添加这两种新方法的原因是“确保与为这些接口(interface)的旧版本编写的代码的二进制兼容性”。

我的问题:

  • 为什么要歪曲界面本来应该是的概念 完全抽象以支持现有的架构问题?
  • 除了类扩展多个接口(interface)的能力之外,使用抽象类和接口(interface)的新版本有什么区别?

最佳答案

The reason java claimed to add these 2 new kind of methods is "ensure binary compatibility with code written for older versions of those interfaces".

这仅适用于默认方法(不是静态方法)并省略了一些上下文。来自 Goetz, State of the Lambda :

The purpose of default methods ... is to enable interfaces to be evolved in a compatible manner after their initial publication.

主要目标是允许接口(interface)进化,即添加新方法。如果将新方法添加到接口(interface),则实现该接口(interface)的现有类将缺少实现,这将是不兼容的。为了兼容,一个实现必须来自某个地方,因此它由默认方法提供。

Why to distort the interface original concept that suppose to be fully abstract in order to support existing architectural problems?

Java 接口(interface)的主要目的是 specify a contract任何类都可以实现而不必改变其在类层次结构中的位置。的确,在 Java 8 之前,接口(interface)是纯粹抽象的。但是,这不是接口(interface)的基本属性。即使包含默认方法,其核心的接口(interface)仍会指定实现类的契约。实现类可以覆盖默认方法,因此该类仍然完全控制其实现。 (还要注意 default methods cannot be final 。)

What is the difference between using an abstract class and the new version of the interface other than the ability of a class to extend multiple interfaces?

类扩展多个接口(interface)的能力与接口(interface)和抽象类的另一个区别密切相关,即接口(interface)不能包含状态。这是允许多重继承的主要困难:如果一个父类(super class)在一个类的祖先中出现多次,那么该父类(super class)的状态会只出现一次还是多次? (这就是所谓的“菱形继承(钻石问题)”。)

另一个区别是抽象类可以通过使用 protected 和包私有(private)的访问级别来定义要与子类共享的方法和字段,但不能与调用者共享。接口(interface)只能有公共(public)方法。

(在 Java 9 中,添加了对私有(private)方法的支持。这对于接口(interface)的默认或静态方法之间的实现共享很有用。)

最后,接口(interface)中的静态方法不影响类继承,也不是接口(interface)契约的一部分。它们只是一种以更方便的方式组织实用方法的方式。例如,接口(interface)中静态方法的常见用途是用于静态工厂方法。如果接口(interface)中不允许使用静态方法,则必须将静态工厂方法放在伴随类中。在接口(interface)中允许静态方法可以让这些方法在适当的时候与接口(interface)本身组合在一起。

关于java - 在接口(interface)中添加默认和静态方法的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29997052/

有关java - 在接口(interface)中添加默认和静态方法的原因的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  6. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  7. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  10. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

随机推荐