以是什么
和为什么
的角度复习 Java面向对象编程
D1
面向对象
- 面向对象:以特征(属性)和行为(方法)的观点去分析现实世界中事务的方式
- 面向对象编程:先使用面向对象的方式进行分析,再使用任意一门面向对象的编程语言进行翻译的过程
类class
- 是什么:人类(对具有相同特征和行为的多个对象共性的抽象描述,在Java语言中包含描述特征的成员变量和描述行为的成员方法,是创建对象的模板)
- 为什么:对象太多了,代码重复量太大,也描述不过来,所以把他们共性的东西提取出来形成一个类!
对象new
- 是什么:我这个人(客观存在的实体,在Java语言体现为内存空间的一块区域)
- 为什么:类是抽象的概念,不能干活,要想干活就得依赖这一类的实体(对象)!
引用
- 是什么:曹阳(在Java语言中使用引用数据类型声明的变量叫做引用型变量,简称为”引用”)
- 为什么:创建对象的实质就是在堆区创建一块存储空间,如果这块空间没有记录下来,下次用的时候就不知道怎么找,为了记录这块存储空间,我们就得声明一个引用!
成员变量和成员方法
- 成员变量:身高、体重(特征)
- 成员方法:吃喝玩乐(行为)
JVM内存结构
- 类:方法区
- 对象:堆区
- 引用:栈区
- 成员变量:静态(方法区),非静态(堆)
- 成员方法:栈区
- 局部变量:栈区,定义在函数中,函数结束内存释放
- 字符串:常量池(堆)
D2
构造方法
- 是什么:方法名与类名相同,没有返回值,void也不写
- 为什么:希望在创建Person对象的同时能够指定姓名和年龄时就需要构造方法!
方法重载
- 是什么:像有参构造和无参构造这样,方法名相同,参数列表的个数、顺序、类型不同,调用方法时可以加以区分,这种关系叫重载
- 为什么:一个方法,需要传递的参数列表不同,这就需要方法重载,方便调用,省得记太多方法名!
this关键字
- 是什么:在构造方法中代表当前正在构造的对象,在成员方法中代表当前正在调用方法的对象
- 为什么:形参变量名和成员变量名相同便于我们知道这个形参变量是给这个成员变量赋值的,但是他们的作用范围不同,就近原则在方法体内成员变量就进不去了,这时就就需要this关键字了
参数传递
- 基本数据类型
- 形参变量的改变不会影响到实参
- 我天生就会笑,随着年龄的增长我还能不会笑了?
- 引用数据类型
- 形参变量指向的内容的改变会影响到实参变量指向的内容
- 我本来不会骑自行车,诶但我学会了
- 引用数据类型
- 形参变量改变指向后再改变指向的内容时不会影响到实参变量指向的内容
- 我本来不会骑自行车也不会编程,但我学了骑自行车没学编程,我编程不还是不会嘛
递归
- 是什么:方法自己调用自己,阶乘,汉诺塔
- 怎么用:找退出条件(n=1) + 规律(n=n) =》 if判断+调用自身
D3
封装
- 是什么:一种保证成员变量值合理性和私密性的机制
- 为什么:main方法不是某个类独有的,不应该放在类里,单独放到一个测试类里。在测试类里可以随便改成员变量信息,合法但不合理,那不行,得封装起来!
- 怎么用:
- 我的车是我自己的(私有化成员变量)只有我能开;
- 我借你开(公有化get和set方法)你才能开,我借你车你开坏了也不行奥(set方法里加判断);
- 听话就可以开走了(构造方法里调set方法)
static关键字
- 是什么:就像在定义类的时候给成员属性或成员方法一个默认值
- 为什么:在Person类实例中国籍都一样,分配不同的内存空间,造成浪费。如果想把国籍都放在一块内存空间就得用到static关键字
- 怎么用:饮水机(被所有对象共享)可以加,水杯不可以加
单例
- 是什么:在main方法中能得到且只能得到Singleton类的一个对象,Singleton类是单例类,任务管理器
- 饿汉式:
- 身份证号有且只能有一个自己的(私有化构造方法);
- 有了身份证号就可以证明有这个人了(本类型的引用指向本类类型的对象),怎么让别人知道有这个人呢你得加个static上个户口,但也不能谁都可以用你身份证号啊你就得加个private;
- 怎么找到这个人呢就得告诉他可以通过身份证号找你(提供公有的get方法负责将上面的对象返回出去),那人家也不知道你身份证号是啥啊你得加个static告诉他
- 懒汉式:
- 黑户不上户口,被抓了才上户口
- 这种情况存在,但可不合理哦,不推荐!
D4
继承extends
- 是什么:教师学生都是人,都得吃饭睡觉(把封装的类中共性的内容提取出来形成一个公共类,其他类吸收这个公共类的机制就叫继承)
- 为什么:除了吃饭睡觉,教师学生也都得喝水,那也不能挨个加啊,直接在人类里加一个就行了(提高代码的复用性、扩展性和可维护性)
- 怎么用:
- 儿子不能跟爸爸平辈也不能管妈妈叫媳妇啊(子类不能继承父类的构造方法和私有方法),爸爸有名儿子也得有名啊,总不能一直叫谁谁谁的儿子吧,但是你也不能跟你爸用一个名吧(私有特征可以继承但不能访问)
- 儿子生出来就遗传了爸爸的基因(当构造子类对象时会自动构造父类的无参构造方法来初始化从父类中继承下来的成员变量,相当于在子类构造方法的第一行增加代码
super();
的效果) - 一个爸爸可以有多个儿子,但一个儿子只能有一个爸爸(Java语言中只支持单继承)
- 儿子必须是爸爸亲生的才能继承他的基因(使用继承必须满足逻辑关系:子类 is a 父类)
方法重写@Override + super
- 是什么:爸爸赚的钱不够花了,你就得自己挣了
- 为什么:Worker类继承Person类调用show()方法是Person类里的,只能打印Person类里有的特征,不能打印Worker类里新加的特征,这个时候就要用方法重写
访问控制
- 自己的东西只能自己用(private修饰的内容只能在本类中使用)
- 方法教你了你爱咋用咋用(public修饰的内容可以在任意位置使用)
包package
- 是什么:就是文件夹
- 为什么:让大家都写一个类,最后命名全是一样的,发给我就冲突了,放在一个不同的目录里就好了(便于管理,避免命名冲突的问题)
- 怎么用:公司或组织域名的反写.项目名.模块名.类名
final关键字
- 是什么:不要孩子,油盐不进,有自己的想法谁也改变不了(本意为”最终的,不可更改的”,该关键字可以修饰类、成员方法、成员变量等)
- 为什么:final关键字防止滥用继承,不经意方法重写或数值的改变
- 对比this:
- this:本类(区分同名的成员变量和形参变量)
- super:父类(使用
super(实参)
的方式可以调用父类的构造方法,使用super.
的方式可以调用父类中被重写的方法)
对象创建的执行流程
- 单个对象:main方法里默认值 =》 显示初始化 =》 构造块 =》 构造方法体 =》 创建完毕
- 子类对象:父类静态代码块 =》 子类静态代码块 =》 父类构造块 =》 父类构造方法体 =》 子类构造块 =》 子类构造方法体
D5
多态
- 是什么:饮料:可乐雪碧红牛(同一事物表现出来的多种形态)
- 为什么:
- 既能打印矩形又能打印圆形(父类Shape)(通过方法的参数传递形成多态,屏蔽不同子类的差异性实现通用的编程带来不同的结果)
- 在方法体中直接用,抽象类/接口不能new对象,只能指向子类对象,当需要更换子类时只需要将new后面的类型修改而其它地方代码不变就立即生效,提高了代码的可维护性
- Calender类是抽象类不能new对象,返回值类型是Calender类型,但实际返回该类子类的对象
- 怎么用:
- 可以通过“林肯他爸”找到他爸,但他爸就是他爸,会修鞋还是会修鞋,儿子能当总统但他爸不是总统(当父类类型的引用指向子类对象时,父类类型的引用可以直接调用父类中独有的方法,不可以直接调用子类独有的方法)
- 披着羊皮的狼,编译父类,运行子类,在内存中子类其实是子类对象,静态的被提成到类层级了(如果子类重写了方法,静态调父类的,非静态调子类的)
类型转换instanceof
- 是什么:分为自动类型转换(子到父) 和 强制类型转换(父到子)
- 为什么:多态不能直接使用子类中扩展的属性和方法,但能通过强制类型转换解决
抽象类abstract
- 是什么:模板(抽象类主要指不能具体实例化的使用abstract关键字修饰的类并且拥有抽象方法的类)
- 为什么:(抽象方法没有方法体,因此调用抽象方法是没有意义的,为了防止程序员不小心调用抽象方法,Java官方就规定抽象类不能new对象)
- 怎么用:
- 就像知道学啥,但啥也不会干,那我要你这对象干啥,但是我可以问问你都学啥,然后自己去学(抽象类的实际意义不在于自身创建对象而在于被继承,当一个类继承抽象类之后必须重写抽象方法,否则该类也变成抽象类)
- 不能和final共同修饰方法(重写和不能重写)
- 不能和static共同修饰(不能调用和可以调用)
- 不能和private共同修饰(不能继承和重写)
接口interface + implements
- 是什么:没有成员变量只有常量,只有抽象方法(特殊的抽象类)
- 为什么:你只有一个爸爸,但是你也想继承你妈妈的基因(黄金既算金属,又算货币,但是Java中只支持单继承,让黄金类同时实现金属接口和货币接口,弥补不能多继承的缺陷)
- 怎么用:
- 类和接口:不同的东西implements,一样的东西extends,有接口就是多的
- 抽象类和接口:abstract class可以有构造方法、成员方法、成员变量,增加方法可以不影响子类(因为可以增加啥方法都行,但是接口只能加抽象方法,实现类必须重写),jdk1.8之后接口可以有非抽象方法了,但必须default
- 接口类型的引用作为方法的形参时,实参可以是实现接口的类的对象,和使用匿名内部类得到接口类型的引用
匿名内部类
- 是什么:如果一段程序中需要创建一个类的对象(通常这个类需要实现某个接口或者继承某个类),而且对象创建后这个类的价值也就不存在了,这个类可以不必命名,称之为匿名内部类
- 为什么:如果这个方法只调用一次,为了它在写一个类在方法区占着一块内存空间,有点浪费,所以就创建一个匿名内部类