1、了解继承

对象继承实际上就是一种“is - a”的关系,如上图的“PantherMan is a SuperHero?”,是,那么便属于继承的理解。

继承能避免大量重复的程序代码,同时非常利于程序扩展(子类可以在复用父类方法的同时定义额外的功能),也定义了共同的协议(确保子类拥有父类的方法)。

另外,值得注意的是,继承是无法继承下父类的private权限的属性和方法的。
 

2、多态的运行

Java中的多态表现为:
  • 静态的多态:如方法重载,方法名相同,参数不同
  • 动态的多态:如子类覆盖父类方法,将子类实例传于父类的引用,调用的是子类的方法;如实现接口的实例,将其传于接口的引用,调用的是实现类的方法。

另外,不光是引用,参数和返回类型也可以多态,但都限于子类到父类,以小到大,不能逆转。

子类继承父类之后,对于父类方法的覆盖时,访问权限不得降低,且方法头必须相同,即方法名,参数和返回类型相同,例外的是返回类型其实也可以是该类型的子类,必须要记住,子类对象得保证能够执行父类的一切。


 

3、深入多态

我们说继承可以帮助我们定义共同类型的对象,比如Animal父类,Cat和Dog作为子类;

当你new Cat我们知道出现了一只猫,当你new Dog我们知道出现了一只狗,当你new Animal?Animal是什么呢?

所以,有些类本来就不应该被初始化,只是一个抽象的概念,但是我们又要用到它的继承来实现多态,怎么办?使用abstract对它进行抽象化。


抽象类其实相对于接口不同的是,它可以有成员变量和具体的方法,甚至构造方法(尽管它不能被实例化),从上面这种抽象的解释来理解,其实也就比较容易了。它的最大的好处就是为了实现多态,如果某个方法我们的参数不使用父类,那么我们必须为每种子类各写一个相同内容仅仅是参数不同的方法,不光是大量重复的代码,一旦需要改动,那才是可怕。

你要问,那干脆把所有的类型都设置为Object不就行了?反正是终极父类,不是吗?这样,实际上你很可能会意外地要求对象去执行错误类型的动作,所以Java设置了一个对代码的保护机制,即“类型安全检查”,当某个对象以父类作为引用时,Java会把它当作父类类型实例,这代表你只能调用父类中声明的方法(即,编译器是根据引用类型来判断有哪些method可以调用,而不是根据你确实的类型),比如:

//编译器没有在Object中找到run()方法,所以第二行无法编译通过
//所以我们才有更多的范围更小的父类,而不是直接甩手用Object来处理
Object cat = new Cat();
cat.run(); // 编译无法通过
 
1
//编译器没有在Object中找到run()方法,所以第二行无法编译通过  
2
//所以我们才有更多的范围更小的父类,而不是直接甩手用Object来处理
3
Object cat = new Cat();
4
cat.run(); // 编译无法通过

4、认识接口

接口的出现,解决了Java不能多重继承的特性,同时比较独特的是,接口相当于一个特殊的抽象类,它没有实例变量,也没有具体方法的实现,有的只是常量和抽象方法。

可是这样一来,我们无法使用接口来完成所谓的“继承”,因为我们没办法复用代码,那么接口的意义在哪里呢?多态,多态,多态,重要的事情说三遍。它会要求你必须履行你们之间的“合约”,也让Java能够放心地把其实现类当作接口类型去使用。

5、对象的生命周期

在Java中,对象生存在堆(heap)上,实例变量是声明在类中,所以实例变量放在所属对象中。需要注意的是,如果实例变量是基本数据类型,那么变量所需要的空间是在对象中。如果实例变量是引用数据类型,那对象只会留下引用量,而引用对应的真正对象本身所要用到的空间则到堆上去取;

而方法调用及其参数,还有局部变量都生存在栈(stack)上,它们的生命周期直到方法调用至执行结束(如果方法中存在对象局部变量,忘了我们在Java基础中说过的吗?这不过是放了个遥控器般作用的引用,真正的对象只会存在堆上)。

而对象生存在堆(heap)上,它们的生命周期随着引用的结束而结束。如果一个对象没有引用(哪怕一个也没有的时候),那么它就等待着被垃圾回收器给带走。


5.1 栈

方法在栈中被 “堆” 在一起,当你调用一个方法时,方法就会放在栈顶,逐步堆叠,然后再逐步执行。 
 

5.2 堆

不管是实例变量还是局部变量,对象本身都会在堆上。而实例变量存在于对象所属的堆空间上。

如果实例变量是基本数据类型,那么Java会根据数据类型的大小留下对应大小的空间。如果实例变量是引用数据类型,是对象,再次记住,也只是留下了对象的引用量的空间,Java不会在这个对象中为其引用对象再留出空间的。
 

另外,实例变量是有默认值的,原始的默认值是 0 / 0.0 / false;引用的默认值是 null。而局部变量没有默认值。

 

6、构造函数和继承的关系

每个父类都有一个构造函数,且每个构造函数都会在子类对象创建时执行。并且会随着继承链不断调用父类构造函数,最终会调用Object的构造函数。为什么会有如此的一个构造链?想一想,小孩能在父母之前出生吗?


调用父类的构造函数,要使用 super(),如果我们没有编写,编译器也会帮我们自动加上调用。如果想要调用父类的代参构造函数,那么同样给super带参就可以了。

如果想要调用自己类中的其他重载的构造函数,使用this(),但是this和super只能择一,不能同时调用。


《Head First Java》读书笔记(2) - Java面向对象思想的更多相关文章

  1. 【java读书笔记】——java开篇宏观把控 + HelloWorld

    学完java有一段时间了,一直没有做对应的总结,总认为有一种缺憾.从这篇博客開始,将自己平时的学习笔记进行总结归纳,分享给大家. 这篇博客主要简单的介绍一下java的基础知识,基本的目的是扫盲.原来仅 ...

  2. [Java读书笔记] Effective Java(Third Edition) 第 7 章 Lambda和Stream

    在Java 8中,添加了函数式接口(functional interface),Lambda表达式和方法引用(method reference),使得创建函数对象(function object)变得 ...

  3. [Java读书笔记] Effective Java(Third Edition) 第 6 章 枚举和注解

    Java支持两种引用类型的特殊用途的系列:一种称为枚举类型(enum type)的类和一种称为注解类型(annotation type)的接口. 第34条:用enum代替int常量 枚举是其合法值由一 ...

  4. [Java读书笔记] Effective Java(Third Edition) 第2章 创建和销毁对象

      第 1 条:用静态工厂方法代替构造器 对于类而言,获取一个实例的方法,传统是提供一个共有的构造器. 类可以提供一个公有静态工厂方法(static factory method), 它只是一个返回类 ...

  5. [Java读书笔记] Effective Java(Third Edition) 第 4 章 类和接口

    第 15 条: 使类和成员的可访问性最小化 软件设计基本原则:信息隐藏和封装. 信息隐藏可以有效解耦,使组件可以独立地开发.测试.优化.使用和修改.   经验法则:尽可能地使每个类或者成员不被外界访问 ...

  6. 【java读书笔记】——java的异常处理

    程序在实际环境的执行过程中.安全成为须要首先考虑的重要因素之中的一个.这也是用户和程序猿最关心的问题.同一时候,Java语言健壮性也体如今了可以及时有效地处理程序中的错误.准确的说是Java的异常处理 ...

  7. [Java读书笔记] Effective Java(Third Edition) 第 5 章 泛型

    第 26 条:请不要使用原生态类型 声明中具有一个或多个类型参数的类或者接口,就是泛型(generic). 例如List接口只有单个类型参数E, 表示列表的元素类型.这个接口全称List<E&g ...

  8. [Java读书笔记] Effective Java(Third Edition) 第 3 章 对于所有对象都通用的方法

    第 10 条:覆盖equals时请遵守通用约定 在不覆盖equals方法下,类的每个实例都只与它自身相等. 类的每个实例本质上都是唯一的. 类不需要提供一个”逻辑相等(logical equality ...

  9. Java 读书笔记 (十七) Java 重写(Override)与重载(Overload)

    重写(Override) 重写是子类对父类的允许访问的方法的实现过程重新编写,返回值和形参都不能改变,即外壳不变,核心重写. // 如果重写不是相当于重新定义了一个方法?那为什么不直接写,还要exte ...

  10. head first java读书笔记

    head first java读书笔记 1. 基本信息 页数:689 阅读起止日期:20170104-20170215 2. 标签 Java入门 3. 价值 8分 4. 主题 使用面向对象的思路介绍J ...

随机推荐

  1. Wincc flexable的按钮组态

    1.题目 2.画面切换按钮组态 1)新建变量 2)组态画面进行命名 3)组态按钮常规 4)组态按钮属性 5)在事件中选择单击,系统函数中选择画面中的ActivateScreen函数切换画面 3.给变量 ...

  2. 【Regular Expression】RE分类及案例

    背景知识 正则表达式分为三类:基础正则表达式.扩展正则表达式.Perl正则表达式(Perl内建) 通俗来说,这三个一个比一个强大,支持的规则匹配字符更多 1.匹配IP ip addr | grep - ...

  3. linux各个文件夹的用途

    英文: /bin: where binary programs live. /boot: the special programs that start the system when you tur ...

  4. 简单利用HTTP中的PUT协议拿下SHELL

    第一次用方法拿shell,之前遇到的都是没有写入权限的. 站太辣鸡,纯粹练手,就不打码了. 此次实战会用到的HTTP请求方法: OPTIONS,PUT,MOVE/COPPY * 战前准备 0x01 什 ...

  5. TC358749XBG:HDMI转MIPI CSI芯片简介

    TC358749XBG是一颗HDMI转MIPI CSI功能的视频转换芯片,分辨率:1920*1080,电源3.3/1.8/1.2,通信方式:IIC,封装形式BGA80

  6. sed修炼系列(一):花拳绣腿之入门篇

    本文为花拳绣腿招式入门篇,主要目的是入门,为看懂sed修炼系列(二):武功心法做准备.虽然是入门篇,只介绍了基本工作机制以及一些选项和命令,但其中仍然包括了很多sed的工作机制细节.对比网上各sed相 ...

  7. Chome——扩展程序,获取更多扩展程序报错

    修改/替换hosts文件 地址:c:/windows/system32/drivers/etc hosts:可从网上搜索下载或网盘下载(链接: http://pan.baidu.com/s/1bpu6 ...

  8. [PSIDE]PeopleSoft PSIDE无法启动因为缺失MSVCR100.dll解决办法

    “The program can’t start because MSVCR100.dll is missing from your computer” 当开发工具是绿色版的时候,在打开PSIDE时很 ...

  9. 学习js函数--函数定义

    函数的定义方法有三种 1.函数表达式 2.函数声明 3,new function构造函数 这边主要看下函数表达式和函数声明 函数表达式(未省略标志的) var alertName = function ...

  10. 如何编写更好的SQL查询:终极指南-第三部分

    本次我们学习<如何编写更好的SQL查询>系列的最后一篇文章. 时间复杂度和大O符号 通过前两篇文章,我们已经对查询计划有了一定了解.接下来,我们还可以借助计算复杂度理论,来进一步深入地挖掘 ...