草庐IT

读Java实战(第二版)笔记08_默认方法

躺柒 2023-04-19 原文

1. 兼容性

1.1. 二进制级的兼容性

1.1.1. 只要不重新编译该类,即使不实现新的方法,现有类的实现依旧可以运行

1.1.2. 现有的二进制执行文件能无缝持续链接(包括验证、准备和解析)和运行

1.1.3. 如果新添加的方法不被调用,接口已经实现的方法就可以继续运行,不会出现错误

1.2. 源代码级的兼容性

1.2.1. 引入变化之后,现有的程序依然能成功编译通过

1.3. 函数行为的兼容性

1.3.1. 变更发生之后,程序接受同样的输入能得到同样的结果

2. 向接口添加方法是罪恶之源

2.1. 二进制级的兼容性

2.2. 不是源码级的兼容

2.2.1. 因为遗留代码并没有实现新引入的方法,所以它们无法顺利通过编译

2.3. 函数行为的兼容性

2.3.1. 因为新添加的方法在程序中并未被调用,抑或该接口在实现中被覆盖了

3. 接口声明方法的2种实现

3.1. 静态方法

3.1.1. 静态方法可以存在于接口内部

3.1.1.1. 辅助类就没有了存在的必要

3.2. 默认方法

3.2.1. 指定接口方法的默认实现

3.2.1.1. 让类可以自动地继承接口的一个默认实现

3.2.1.2. 不显式地提供该方法的具体实现,就会自动继承默认的实现

3.2.2. default修饰符

4. 为API创建不同的发布版本,同时维护老版本和新版本

4.1. 增加了作为类库的设计者维护类库的复杂度

4.2. 类库的用户不得不同时使用一套代码的两个版本

4.2.1. 项目使用的类文件数量更多了

4.2.2. 增大内存的消耗

4.2.3. 延长程序的载入时间

4.3. 费时费力的

5. 默认方法

5.1. 缺失的方法实现会作为接口的一部分由实现类继承(所以命名为默认实现),而无须由实现类提供

5.2. 由default修饰符修饰,并像类中声明的其他方法一样包含方法体

5.3. 函数式接口只包含一个抽象方法,默认方法是种非抽象方法

5.4. 主要目标用户是类库的设计者

5.4.1. 为接口的演进提供了一种平滑的方式

5.4.2. 兼容的方式解决像Java API这样的类库的演进问题的

5.4.3. 让类库的设计者放心地改进应用程序接口,无须担忧对遗留代码的影响

5.4.4. 为方法的多继承提供了一种更灵活的机制

5.4.4.1. 类可以从多个接口继承默认方法

5.4.4.2. 帮助你更好地规划你的代码结构

5.5. 使用模式

5.5.1. 可选方法

5.5.1.1. 类实现了接口,却刻意地将一些方法的实现留白

5.5.1.2. 可以减少无效的模板代码

5.5.1.2.1. 已经有一个默认的实现
5.5.1.2.2. 不需要再声明一个空的方法

5.5.2. 行为的多继承

5.5.2.1. 构造Java语言中的多继承

5.5.2.2. Java的类只能继承单一的类

5.5.2.3. 一个类可以实现多接口

5.5.2.3.1. 类可以从多个接口中继承它们的行为(即实现的代码)

5.5.2.4. 保持接口的精致性和正交性能帮助你在现有的代码基上最大程度地实现代码复用和行为组合

5.5.2.4.1. 利用正交方法的精简接口
5.5.2.4.2. 组合接口
5.5.2.4.3. 通过精简的接口,你能获得最有效的组合,因为你可以只选择需要的实现

6. 关于继承的错误观点

6.1. 不应成为代码复用就试图倚靠的“万精油”

6.2. 从一个拥有100个方法及字段的类进行继承就不是个好主意

6.2.1. 使用代理有效地规避这种窘境

6.2.1.1. 创建一个方法通过该类的成员变量直接调用该类的方法

6.2.2. 声明为final的类不能被其他的类继承,避免发生这样的反模式,防止核心代码的功能被污染

7. 解决冲突的规则

7.1. 解决可能的二义性(模糊性)问题

7.1.1. 菱形继承问题

7.1.1.1. 一个类同时继承了具有相同函数签名的两个方法

7.2. 类中的方法优先级最高

7.2.1. 类或父类中声明的方法的优先级高于任何声明为默认方法的优先级

7.3. 如果无法依据第一条进行判断,那么子接口的优先级更高

7.3.1. 函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体

7.4. 如果还是无法判断,那么继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现

7.4.1. 引入了一种新的语法X.super.m(...),其中X是你希望调用的m方法所在的父接口

8. 定义接口以及工具辅助类(companion class)是Java语言常用的一种模式

9. 抽象类和抽象接口

9.1. 一个类只能继承一个抽象类

9.2. 一个类可以实现多个接口

9.3. 一个抽象类可以通过实例变量(字段)保存一个通用状态

9.4. 接口是不能有实例变量的

有关读Java实战(第二版)笔记08_默认方法的更多相关文章

  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 方法() 方法 - 2

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

  6. 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

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

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

  8. 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

  9. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  10. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

随机推荐