独立完成酒店管理,写作业。 ,复习前面知识点,做一遍前面习题,整理习题,整理知识点,看完巴菲特书
JVM特性:4个 跨平台,面向对象,多线程,自动垃圾回收机制
面向对象特性:封装性,继承性,动态性(多态),抽象
软件设计6大原则 需要了解了解
1 单一职责原则 : 功能职责单一,只拥抱一种变化
- 2 里氏替换原则 : 所有在使用父类的情况下,都可以使用子类
- 3 依赖倒置原则 : 高层通过抽象依赖底层,
- 4 接口隔离原则 : 不应该依赖于它不需要的接口
- 5 迪米特原则 : 最少知识原则
- 6 开闭原则 : 对扩展开放,对修改关闭
http://baijiahao.baidu.com/s?id=1645013441658118287&wfr=spider&for=pc
多态:就是里氏替换原则的一种体现 父类引用 指向 子类对象
父类引用:父类型声明的引用变量 指向:就是通过这个引用类型变量可以找到谁 子类对象:new的子类对象
通过父类创建一个引用类型的变量,可以找到子类的对象 父类 变量 = new 子类();
Animal a = new Cat();
变量声明 : 数据类型 变量名 = 值;
变量分类 :局部变量 (1 方法内部声明、2 参数列表声明) 静态变量 成员变量
有变量的地方 就可以发生多态,并且多态是发生在赋值的时候------------> Animal a = new Cat();
多态发生的几种形式
1 直接多态 不管成员变量还是局部变量 直接声明式多态 父类 变量 = new 子类();
2 形参和实参 方法参数定义时 使用父类定义,调用方法时,传递子类对象
3 返回值 返回值类型定义为父类, 返回数据的时候返回子类对象
多态的缺点 : 丢失子类特有的属性
多态调用属性 :
1 如果调用的是父类没有的,直接报错,都访问不了
2 如果调用的是子类没有的,都访问父类的
3 如果调用的是父类和子类都有的,那么除了成员方法调用子类的之外,其他的都调用父类的,因为成员方法可以覆写
多态得到前提条件
1 必须有继承关系的体系中(父,子,爷,孙 都可以)
2 多态又叫向上转型
优点:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
/*1.5 缺点(扩展)
丢失 子类特有的属性
为什么?
- 多态缺点 丢失子类特有的属性,特有属性需要向下转型后 再进行访问
- 并且 是编译时异常
- 程序从开发到运行的完成生命周期
-
编译阶段 : 在编译阶段的时候,父类文件有,子类文件也有,子类对象没有,但是我们在代码中已经定义了多态
-
这个时候,编译器会直接按照父类类型来划分空,来说明空间中有啥,来检查语法结构
-
这个时候 只能找到父类里面的属性说明,因为空间是父类声明的
-
什么时候有的子类对象? 运行时
-
运行阶段
-
各个类载入方法区,开始运行,执行new 创建对象,对象用子类Cat创建的,所以 对象中是包含子类 特有属性的
-
但是引用变量的类型是父类类型,并且在编译时就已经进行了静态绑定,所以 使用这个父类声明的空间的时候就只能找到父类中有的
-
而 子类对象中 有的特有属性 是没有办法通过父类的变量找到的
-
因为 父类的变量声明的时候 只能够说明父类的属性列表,而创建对象之后,使用子类声明的属性值列表
-
按说 创建了对象,对象中有子类属性,为什么找不到? 因为在编译时就报错了,语句不通过,压根等不到运行时
- 等于 使用父类的属性列表去调用 子类的属性值列表 是找不到
- 编译时 :
-
在编译的时候,会把父类的属性生成一个属性列表,父类属性有了,这叫编译时绑定,绑定完之后,程序就有了,属性就已经固定了
-
属性值没有固定(都没有运行,没有空间,哪来的值?)
-
这种编译时绑定,又可以叫做静态绑定/前绑定
- 运行时 :
-
运行的时候,把类生成对应的对象,也有了子类的属性列表,因为创建了对象,有了空间.进行了初始化操作,所以属性的值也就有了
-
这种在运行阶段进行的数据绑定叫运行时绑定/动态绑定/后绑定
- 调用时 :
-
使用父类的引用,调用子类对象的属性的时候(特有的就访问不到了)
-
也可以理解为 使用父类的属性列表 去调用子类的属性值列表
-
所以问题就出现了,这样子类特有的就没有办法找到了
因为 使用的是父类的属性列表进行调用匹配,所以在找不到的时候语法就不通过了,所以在编译时就会报错,压根不能运行,不运行就没有对象,没有对象就更别提能不能找到特有数据了
*
- super : 官方说法是 代表了父类型特征,这里就可以理解为父类的属性列表 */
/**1.6 隐式多态(扩展)
* this : 谁调用,this就是谁 所以 这里this 一定是 subClass 这个子类对象
*
* this 是保存当前对象的内存地址,并且是第一个成员变量,既然是变量,那么总得有数据类型吧?
*
* this 用来存储当前对象的内存地址,那么 this的数据类型为 什么的时候 可以存储当前对象内存地址?
* 1 当前类类型
* 2 父类类型
* 如果是父类类型的话,就是多态,父类引用指向子类对象,缺点就是不能调用子类特有的属性,而 this 是可以调用当前类的特有属性的
* 所以 this的类型 是 当前类 类型
*
* 什么是当前类? : 当前类 就是 this所在的类(在哪个类出现的 ,哪个就是当前类)
*
* 那么 这里的this 就等于是 SupClass this
*
* 那么 this的引用 是子类对象,再结合this 是当前类类型 所以成了这样 SupClass this = new SubClass(); */
注意:在第一行 package 下面报错,一般是因为有类名冲突
可以检查一下 是否 存在 一个java文件中 创建了多个 class 并且有class同名
导包出错,傻眼了吧,因为当前包下,有一个和导入同名的类,就会出现这种问题。可以使用类全名解决 建议 不要和已有类同名,尤其是系统类
.Instanceof
- 多态又叫向上转型,可以看做自动类型转换,从子类到父类
- 向下转型,可以看做强制类型转换,从父类到子类,必须先发生向上转型
- instanceof 判断该对象是否有某个类实例化而来
- Abstract
抽象类往往用来表示设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
比如:动物,它只是一个抽象的概念,并没有一个 “东西”叫做 “动物”。所以,它并不能代表一个实体,这种情况下,我们就适合把它定义成抽象类。
-
abstract 是修饰符
-
使用abstract 修饰的类,是抽象类
-
使用abstract 修饰的方法,是抽象方法,抽象方法没有方法体,只有功能 定义,没有功能实现,用于让子类实现
-
实现抽象方法,就是给抽象方法加上方法体,去掉abstract修饰
-
抽象类的目的 : 该类不能被实例化对象,只能被继承
-
抽象方法一定在抽象类 中,成立
-
抽象类中一定有抽象方法,不成立,也可以没有,如果就想让某个类不能创建对象,也可以把该类创建类抽象类
-
final修饰的类不能被继承,
-
final修饰的成员方法不能被覆写
-
而 抽象类 就是用于被继承的,抽象方法就是用于被实现覆写的
-
所以 final 和 abstract 不能同时出现!!
-
一个类 如果要继承一个抽象类,必须要实现该类的所有抽象方法
-
一个抽象类 如果要继承一个抽象类 可以实现 0~N个抽象方法(可以实现,也可以不实现)
4.Interface
4.1 是什么
-
引用数据类型 : 类 数组 接口
-
接口是一种引用数据类型,可以看做是一种特殊的类,是java为了解决没有多继承引起的功能变弱的问题
-
一个类只能有一个父类,但是可以实现N个接口
-
创建接口的方式 由 class 变成了 interface 而 父子关系 用 extends 变成了 implements
-
类和类 使用extends,并且单继承
-
类和接口 使用 implements 多实现 多个以逗号隔开,比如 class A implements V,C,D
-
并且 非抽象类实现接口后,必须实现所有的抽象方法
-
抽象类实现接口后 可以实现 0~N个抽象方法
-
接口和接口 使用 extends,并且是多继承 比如 interface A extends B,C,D
-
语法 :
-
public interface 接口名{
-
}
-
1 接口中 所有的变量 默认都是 public static final 的 也就是常量 ,而且 public static final 可以省略
-
2 接口中的方法 默认都是 public abstract 的 也就是抽象方法,而且 public abstract 可以省略
-
3 接口中没有构造方法,不能被实例化对象
-
从 java1.8开始 接口中 可以有 静态方法和默认方法 (default方法需要使用实现类对象调用。因为接口不可创建对象。接口中默认方法,就等于已实现的成员方法)
-
接口可以看做是一个特殊的抽象类,所以很多时候 接口和抽象类都能做到某一件事
-
优先使用接口,因为 类和接口之间是多实现, 当使用接口之后,还可以保留类的继承