美文网首页
EffectiveJava笔记[四]

EffectiveJava笔记[四]

作者: pigrange | 来源:发表于2019-07-23 20:55 被阅读0次

【序】今天睡懒觉了,差点咕咕咕。(手动换行) 昨天试图分享自己的笔记,结果被吐槽只是抄书。这句话的对做为尝试写总结性质读书笔记的新手(我)的打击性其实是很大的。花了近3小时写的文章(姑且算是),结果被别人看了一眼就说你这就是抄书,没有技术含量,也不算是原创。

  • 无能狂怒:这是本人初次尝试通过记录笔记并公开分享,也是尝试对费曼学习法的一次尝试,如果你不喜欢或者觉得没有任何价值。只能抱歉,这确实是我的问题,请自行关闭。这个系列我还是会写,可能后期渐渐改变写作风格。当前的格式很受此书的影响(这本书本来就是总结性质的),只能说前几篇确实是写得太过于仓促有一点依葫芦画瓢的感觉吧。

  • 为什么做这个系列:在才开始看EffectiveJava的几天,我其实是并没有这个打算的,因为此书本身是总结性质的,但是由于有不少的地方比较难,在网上搜索相关的内容大多都是完整的抄书没有得到实质性的讲解。所以打算自己总结来加深理解。

  • 定位:帮助自己学习和理解JAVA,当然希望对别人有用。


16、在公共类中使用访问方法而不是公共属性

关键字:public类访问方法public属性

JAVA里面,对于那些需要对外提供某些属性的类。比较建议的一种写法是对外提供访问方法(gettersetter)而不直接将这些属性设置为public的。曾经有人问过我这个问题,为什么要这么做,我并不知道,只觉得这是封装思想的一种体现。

如下(例子源于书上):

//不建议这样写
class Point {
    public double x;
    public double y;
}

//建议这样写
class Point {
    private double x;
    private double y;

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }
}

理解:

  • 这其实是类和成员可访问性最小化的一个体现。外界通过唯一publicAPI来获取数据。类本身将其具体的实现隐藏,这样内部的实现无论怎么改只要返回给外界他们期望的值即可。相对的,如果直接将属性提供给外界的话,那么在一个成型的代码系统中,这个属性就几乎没有再修改的余地了。

例外:

  • 如果一个类是包级私有的或者是一个私有的内部类,这样写是被允许的。理由很简单,它们对外提供的属性的作用范围太小了,并不会出现上面提到的那种问题。而且这样写的可读性更强,不是吗?(手动斜眼)

17、最小化可变性

关键字:可变性

首先我们给不可变的类一个基本的定义:

  • 不提供任何修改对象状态的方法
  • 不能被继承
  • 所有的属性均为final。(即便这个属性是private的,因为你无法保证在编写逻辑的时候不修改某个属性的值,而设置为final后,当你不经意修改的时候会出现错误提醒你)
  • 所有的属性应该是private的。(其实设置为public并不会出现任何问题,但是这违背了条目16的建议)
  • 确保对任何可变组件的互斥访问。(这是什么意思呢???)

理解:

  • 在创建的一开始它的状态就被确定了,状态在它存在的整个生命周期均不会发生任何改变。

  • 线程安全的,不需要线程同步。因为不可变的对象的所有属性都是只读的,它并不会因为多线程的同时访问而出现同步问题。

  • 可以自由的分享,也没有必要创建很多个副本或者考虑防御性拷贝。

缺点:

为每一个不同的值都需要创建一个单独的对象,导致性能问题。

总结:

除非有很好的理由能够说明一个类应该是可变的,否则尽量将其设置为不可变的。


18、组合由于继承

关键词:组合继承

跨越包级的继承很危险(对类来说)的。

  • 破坏了封装的思想:子类有可能会依赖父类的一些实现细节,但是父类改变后,可能会导致子类无法使用。
  • 重写父类的方法不一定有效:在出现了上面的问题的时候,一个解决方案就是重写父类的方法,但是如果这个逻辑涉及到一些父类中的私有属性的话,那么将无法实现。(子类并不能访问父类的私有属性)
  • 随着父类新版本的发布,父类可能会提供新的方法。但是这可能会对子类进行破坏(如果正好子类拥有一个相同名字参数和返回类型的方法),从而导致编译不通过。

组合:

不继承一个现有的类,而是在新的类里面持有一个私有的现有类的对象。对于现有类的一些实现,新的类实现一个同名方法并在内部调用现有类的方法。

优点:

  • 新类并不依赖现有类的实现细节,所以现有类的修改并不会对新类产生影响。

理解:

  • 这是一种基于包装类的思想,即设计模式中的装饰者模式。
  • 这种设计模式并不等同于委托

注意:

  • 包装类中不适合使用回调,因为某一些设置回调的方法对象会将自我的引用返回出来,但是被包装的对象是并不知道它的外界存在一个包装器,所以它仍然会返回一个自身的引用。

总结:

适合使用继承的情况:只有子类真的是父类的子类型的情况下才适合使用继承。即两者中存在"B is A"的关系,才应该让B继承A。


19、要么设计继承并提供文档说明,要么就禁用继承

如题,字面意思。

可继承的类:

  • 如果一个类是可以被继承的话,那么我们应该提供详细的文档说明

    • 详细描述重写某一个方法会带来的影响。
    • 应当说明可重写方法的自用性
    • 应当详细的列出任何可能调用可重写方法的情况
  • 测试一个为继承而设计的类的唯一方法是编写子类进行测试

  • 构造方法里面不能直接或间接地调用可重写的方法

禁用继承:

  • 如果无法提供很好的设计或文档,那么就将此类设置为final以禁用继承

总结:

  • 设计一个可继承的类需要提供详细的文档,并且需要很大程度上限制这个类的功能。
  • 如果不得不继承一个没有提供详细文档的类,最好的方法是不调用任何可重写的方法(消除父类自用可重写方法的可能性)。

20、接口优于抽象类

关键字: 接口抽象类

JAVA对于抽象类只允许单一继承,而对于接口来说可以多实现。

理解:

JAVA对类的继承的结构是垂直的,也就是说一个类继承了它的父类,那么它就一定满足"A is B"的描述,也就是说,它的根源是被确定了的。

但是接口只是一种实现,它对外表述的是"A can be B",这表示A是多变的,它强调了A是具有某一些行为是符合它被作为B的要求,所以它应该是有多种实现的。

  • 抽象类过分的强调了层级关系,这对于我们并不能准确定义某一些类的层次。比如说一个程序员也可能是一个作家,但是如果使用抽象类我们就无法给它一个精确的定义。
  • 实现了接口的类可以很方便的实现其他接口以更新功能,但是如果是实现了抽象类,那么就会比较麻烦。
  • 接口是定义mixin(混合类型)的理想选择,它保证了一个类除了提供自身类型以外,还能够提供某些可以选择的行为。

相关链接:
EffectiveJava笔记[一]
EffectiveJava笔记[二]
EffectiveJava笔记[三]

相关文章

  • EffectiveJava笔记[四]

    【序】今天睡懒觉了,差点咕咕咕。(手动换行) 昨天试图分享自己的笔记,结果被吐槽只是抄书。这句话的对做为尝试写总结...

  • EffectiveJava笔记[三]

    11、重写equals时重写hashCode方法 在每一个重写了equals方法的类中,应当重写这个类的hashC...

  • EffectiveJava笔记[二]

    6、避免创建不必要的对象 此条目下作者有这个观点:当你应该重用现有对象的时候,请不要创建新的对象 最突出的就是字符...

  • EffectiveJava笔记[一]

    1、考虑使用静态工厂方法代替构造方法: 静态工厂方法的优点: 拥有名字,更加容易阅读 不需要每一次调用的时候都创建...

  • 覆盖equals时请遵守通用约定

    上次在公众号发布了一篇EffectiveJava的笔记创建和销毁对象,有人反应字数太多了,一下子看不过来,于是我考...

  • EffectiveJava读书笔记一

    第2章 创建和销毁对象 1. 考虑用静态工厂方法代替构造器 静态工厂相比构造器的优点来说如下: 有名称 不必每次创...

  • EffectiveJava读书笔记二

    第3章 对于所有对象都通用的方法 覆盖equals时请遵守通用约定 在覆盖equals会出现意料不到的错误,在以下...

  • EffectiveJava读书笔记三

    第4章 类和接口 使类和成员的可访问性最小化 模块之间只通过它们的API进行通信, 一个模块不需要知道其他模块的工...

  • 单例模式

    单例模式 最近在看《剑指offer》,根据《剑指offer》的讲解,结合《effectiveJava》简单学习了一...

  • EffectiveJava 学习记录 一

    第一章 前言 学习摘要 第二章 创建和销毁对象 学习主题 学习摘要 2017/7/4 23:15:43

网友评论

      本文标题:EffectiveJava笔记[四]

      本文链接:https://www.haomeiwen.com/subject/erhzlctx.html