在带有继承结构的标准Javabean类中
多态
包(Package):为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间
作用:
- 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用
- 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突
- 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类
一个包可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。
以下是一些 Java 中的包:
java.lang - 打包基础的类
java.io - 包含输入输出功能的函数
开发者可以自己把一组类和接口等打包,并定义自己的包。而且在实际开发中这样做是值得提倡的,当你自己完成类的实现之后,将相关的类分组,可以让其他的编程者更容易地确定哪些类、接口、枚举和注释等是相关的
由于包创建了新的命名空间(namespace),所以不会跟其他包中的任何名字产生命名冲突。使用包这种机制,更容易实现访问控制,并且让定位相关类更加简单
final关键字:可以用于修饰类,成员变量,成员方法
特点:
- 它修饰的类不能被继承
- 它修饰的成员变量是一个常量
- 它修饰的成员方法是不能被子类重写的
- final修饰的常量定义一般都有书写规范,被final修饰的常量名称,所有字母都大写,且final修饰成员变量,必须初始化,初始化有两种
a. 显示初始化;
b. 构造方法初始化。
c. 不能两个一起初始化
封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为
整体 与 零散的属性与行为(方法)
类中重复的东西越来越多 --> 继承
然而没有继承,就没有多态
new Student(); 创建一个学生对象
Student s = new Student(); 赋值给学生类型
Person p = new Student(); 赋值给人的形态
多态的应用场景
public void register(Teacher t) {
// 方法里面是注册的代码逻辑
}
public void register(Student s) {
// 方法里面是注册的代码逻辑
}
public void register(administrator a) {
// 方法里面是注册的代码逻辑
}
-->
继承于Person都可以使用这个逻辑
根据传递对象的不同,还可以调用不同的show方法
public void register (Person p) {
p.show();
// 方法里面是注册的代码逻辑
}
同类型的对象,表现出不同的形态
表现形式 : 父类类型 对象名称 = 子类对象;
前提
- 有继承/实现(与接口有关)关系
- 有父类引用指向子类对象(子类对象赋值给父类类型) Fu f = new Zi(); 等号左边父类类型的变量 指向 等号右边new出来的子类对象
- 有方法重写
好处
使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利性
多态调用成员的特点
- 变量调用:编译看左边(看父类有没有),运行也看左边(获取打印)
- 方法调用:编译看左边(看父类有没有),运行看右边(获取子类的覆盖打印)
在Java中加载字节码文件的时候,永远先加载父类,然后再加载子类(Object -> Animal -> Dog)
方法会重写覆盖,而成员变量不会(可以同时存在多个name)
记录其父类的位置,也即联系上其父类
多态的优势
- 在多态形势下,右边对象可以实现解耦合,便于扩展和维护
Person p = new Studnet; p.work(); // 业务逻辑发生改变时,后续代码无需修改(只需要修改new Student即可)
- 在其他地方(测试类中)定义方法时,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
多态的弊端
不能使用子类的特有功能(编译看左边)
- 引用数据类型的类型转换有2种
- 自动类型转换
- 强制类型转换
- 可以转化成真正的子类类型,从而调用子类独有功能
- 转换类型与真实对象类型不一致会报错(狗的对象 不能 转换成 猫的类型 ClassCastException类型转换异常)(且为从右向左转)
- 转换的时候用 instanceof 关键字进行判断
- 可以转化成真正的子类类型,从而调用子类独有功能
Person p = new Student(); // 由小变大自动
Student s = (Student) p; // 由大变小强制