【Java编程思想读书笔记】第七章:复用类+第八章:多态

参考书目:《Java编程思想》(第四版)
友链:【读书笔记】Java重要知识点整理与汇总

阅读《Java编程思想》(第四版)一书收获颇多,之所以想通过用博客记笔记的方式来读书,是因为这样可以倒逼自己仔细、反复地阅读书中的知识,找相对意义上的重点,并且由于人脑更适合输出型的学习,通过将内容边看、边记、边理解和边打字写文,相比直接反复阅读更有效益(当然这本书后续仍需反复阅读几十遍甚至百遍以上都不为过),而另一个原因就是这样也能够在阅读中通过博客来记录自己的学习历程,博客记录的不只是图文,它们记录的正是自己的成长,等以后毕业或者工作后,回首大学四年,多少有点可以回念的东西,还可以说一句:一路走来,我读了很多前辈们的好书,对技术充满了热情,永远在不断学习的路上。

start.作者讲授思路:
【Java编程思想读书笔记】第七章:复用类+第八章:多态_第1张图片
【Java编程思想读书笔记】第七章:复用类+第八章:多态_第2张图片

1.@Override注解:当你想要覆盖某个方法时,由于不留心导致重载了该方法而并未覆盖该方法,那么编译器回产生一条错误信息。

2.到底是用组合还是用继承,一个最清晰的判断办法就是问一问自己是否需要从新类向基类进行向上转型,如果必须向上转型,则继承是必要的,但如果不需要,则应当好好考虑自己是否需要继承。

3.类中所有的private方法都隐式地指定为是final的,由于无法取用private方法,也就无法覆盖它,可以对private方法添加final修饰词,但这并不能给该方法增加任何额外的意义。

4.如果某方法是private,它就不是基类的接口的一部分,它仅是一些隐藏于类中的程序代码(private方法属于final方法,并可被自动认为是final方法,对导出类是屏蔽的),只不过是具有相同名称而已。但如果在导出类中以相同的方法名称生成一个public、protected或包访问权限方法的话,该方法就不会产生在基类中出现的“仅具有相同名称的情况”。此时你并没有覆盖该方法,仅是产生了一个新的方法。由于private方法无法触及且能有效隐藏,所有除了把它看成是因为它所归属的类的组织结构的原因而存在外,其他任何事物都不需要考虑到它

5.设计类时,将方法指名是final的,应该说是明智的,这会让别人不去覆盖你的方法。然而要预见类是如何被复用的一般是困难的,如果考虑不周,可能会妨碍其他程序员通过继承来复用你的类。

6.在Beetle上运行java时,所发生的第一件事就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Bettle类的编译代码(在名为Beetle.class的文件中),在对它进行加载的过程中,编译器注意到它有一个基类(这是由关键字extends得知的),于是会继续加载这个基类,不管你是否打算产生一个基类的对象,这都要发生。如果基类还有其自身的基类,那么这个基类的基类也会被加载,以此类推。最终,根基类的static初始化即被执行,然后是它紧接着下面的那个导出类以此类推,这种方式很重要,因为导出类的static初始化可能会依赖于基类成员能否被正确初始化

7.设计一个系统时,目标应该是找到或创建某些类,其中每个类都有具体的用途,而且既不会太大(包含太多功能而难以复用),也不会太小(不添加其他方法就无法使用)。如果你的设计变得过于复杂,通过将现有类拆分为更小的部分而添加更多的对象,通常会有所帮助。

8.名词介绍:

  • 封装:通过合并特征和行为来创建新的数据类型。
  • 实现隐藏:通过将细节私有化把接口和实现分离开。
  • 多态:用于消除类型之间的耦合关系。

  • 绑定:将一个方法调用同一个方法主体关联起来。
  • 前期绑定:由编译器和连接程序实现,在程序执行前进行绑定。它是面向过程的语言中不需要选择就默认的绑定方式。
  • 后期绑定:运行时根据对象的类型进行绑定。也叫做动态绑定或运行时绑定。如果一种语言要实现后期绑定,就必须具有某种机制,以便在运行时能判断对象的类型,从而调用恰当的方法,也就是说,编译器一直不知道对象的类型,但是方法调用机制能找到正确的方法体,并加以调用。后期绑定的机制随编程语言的不同而有所不同,但不管怎样都必须在对象中安置某种“类型信息”。

9.Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。因此将一个方法声明为final时,不仅可以防止他人覆盖该方法,还可以“关闭”动态绑定,这样,编译器就可以为final方法调用生成更有效的代码(Java的早期可以,但如今不需要了,所以最好根据设计来决定是否使用final,而不是出于提高性能的目的)。

9.向上转型,也就是在继承层次中向上移动,是安全的,因为基类不会具有大于导出类的接口,因此,通过基类接口发送的消息都能保证被接受

10.基类的构造器总是在导出类的构造过程中被调用,而且按照继承层次逐渐向上链接,以使每个基类的构造器都能得到调用。这样做是有意义的,因为构造器具有一项特殊任务,检查对象能否被正确地构造。导出类只能访问自己的成员,不能方法基类的成员(因为通常为private类型)。只有基类的构造器才具有恰当的知识和权限来对自己的元素进行初始化。因此,必须令所有的构造器都得以调用,否则就不可能正确构造完整对象,这正是编译器为什么要强制每个导出类部分都必须调用构造器的原因,在导出类的构造器主体中,如果没有明确指定调用某个基类构造器,它就会默认调用默认构造器,如果不存在默认构造器,编译器就会报错(如果某个类无任何构造器,编译器就会自动合成出一个默认构造器)。

例子:

class Meal {
     
    Meal() {
     
        System.out.println("Meal()");
    }
}

class Bread {
     
    Bread() {
     
        System.out.println("Bread()");
    }
}

class Cheese {
     
    Cheese() {
     
        System.out.println("Cheese()");
    }
}

class Lettuce {
     
    Lettuce() {
     
        System.out.println("Lettuce()");
    }
}

class Lunch extends Meal {
     
    Lunch() {
     
        System.out.println("Lunch()");
    }
}

class PortableLunch extends Lunch {
     
    PortableLunch() {
     
        System.out.println("PortableLunch()");
    }
}

public class Sandwich extends PortableLunch {
     
    private Bread b = new Bread();
    private Cheese c = new Cheese();
    private Lettuce l = new Lettuce();
    public Sandwich() {
     
        System.out.println("Sandwich()");
    }
    public static void main(String[] args) {
     
        new Sandwich();
    }
}

运行结果:
【Java编程思想读书笔记】第七章:复用类+第八章:多态_第3张图片

你可能感兴趣的:(Java,java,编程语言)