1. 分类思想实现信息管理系统
在Java基础阶段,对于信息管理系统的实现方式为:在主方法中调用 添加、删除、修改、查看等方法实现信息管理。这种实现方式会出现重复代码过多、业务逻辑聚集、可维护性差等问题。(代码在我的资源中,信息管理系统 v1.0)
未来的开发采用的是分类思想:即分工协作,专人干专事。在IDEA模块中用5个包管理不同功能的java文件,分别为entry、domain、controller、service、dao。
- entry:是程序的入口包含main方法。
- domain:只存放javabean类。
- controller:只负责与用户打交道。(接收用户需求,采集用户信息,打印数据到控制台)
- service:只用来进行业务逻辑的处理。(例如: 判断录入的id是否已经存在于数组)
- dao: (Data Access Object 缩写) 只用于访问存储数据的数组或集合。
(信息管理系统 v2.0采取分类思想,在我的资源中,为IDEA模块)
在使用分类思想开发时,可以充分利用面对对象思想:我们假设每个新建的类所有功能已经写好,我们暂时不需要关心功能是如何实现的,需要时直接调用方法即可,在完成当前类中代码后,再去实现所调用的方法的代码。
2. static关键字
static 关键字是Java中的一个修饰符,可以修饰成员方法和成员变量
static修饰的特点:
1. 被static修饰的成员,被该类的所有对象所共享:
package com.yulufeng.static_test;
public class Student {
int id;
String name;
static String school;//被static修饰的成员变量会被所有新建的对象共享
public void show(){
System.out.println(id +"...."+ name +"..."+ school);
}
}
package com.yulufeng.static_test;
public class StaticTest01 {
public static void main(String[] args) {
Student stu1 = new Student();
Student stu2 = new Student();
stu1.id = 1001;
stu1.name = "呼保义";
stu1.school = "梁山好汉大学";
stu1.show();//1001....呼保义...梁山好汉大学
//stu2的school没有被赋值,但school为静态成员别共享
stu2.show();//0....null...梁山好汉大学
}
}
2. 被static修饰的成员,可以被类名直接调用(建议使用此方式调用)
3. 被static修饰的成员,会随着类的加载而加载,优先于对象存在:
- 静态方法中只可以访问静态成员方法和变量
- 静态方法中没有this关键字(this表示当前对象的引用,而静态方法优先于对象存在)
3. 继承
- 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义、追加属性和方法。
- 继承优点:提高了代码的复用性和可维护性。
- 继承缺点:降低了代码的灵活性(子类必须拥有父类的非私有属性和方法),增强了代码的耦合性(代码与代码之间的关联)。
- 当类与类之间存在相同内容,并且产生了is a 的关系时,可以考虑使用继承实现代码的优化。
- Java中类只支持单继承和多层继承,不支持多继承。(同时继承多个类会导致逻辑混乱)
- this关键字:代表本类对象的引用
- super关键字:可以理解为父类对象引用
3.1 方法重写
方法重写概念:子类出现了和父类中一模一样的方法声明。(方法名、参数列表、返回值类型都必须一样)
应用场景:当子类需要父类的功能,而且子类需要有自己特有内容时,可以重写父类中的方法,即沿袭了父类的功能,又定义了子类特有的功能。
Override注解:用来检测当前的方法,是否为重写的方法,起到【校验】的作用。
父类:
package com.yulufeng.static_test;
public class IPhonev1 {
public void call(String name){
System.out.println("给" + name + "打电话");
}
public void voiceAssistant(){
System.out.println("speak English");
}
}
子类:
package com.yulufeng.static_test;
public class IPhonev2 extends IPhonev1{
@Override
public void voiceAssistant() {
super.voiceAssistant();//父类功能
System.out.println("说汉语");//自己特有功能
}
}
方法重写的注意事项:
- 子类不能重写父类私有方法(private修饰)
- 静态方法本质上不能被重写,如果子类重写了父类的静态方法@Override会报错。如果子类存在与父类一模一样的静态方法,可以理解为将父类同名的方法隐藏起来,而并非重写
- 子类重写父类方法时,访问权限必须大于等于父类方法的修饰符权限(public > protected > 默认 > private)
权限修饰符:
3.2 继承中构造方法的访问特点
子类在初始化的时候,有可能会用到父类的数据,所以子类在初始化之前,一定要先完成父类数据的初始化。不管调用子类的空参还是有参构造方法,都会默认访问父类的无参构造方法。
子类是如何访问到父类的无参构造方法的?
- 系统在每一个构造方法中,默认隐藏一句代码 super() 用于访问父类无参构造方法。
- 如果我们自己编写的类,没有指定父类,系统也会自动继承Object类。
如果父类没有空参构造方法如何解决?
- 子类通过使用super( ),手动调用父类的带参的构造方法。
- 子类通过this( )调用本类其他的构造方法,本类的其他构造方法再通过调用super()去手动调用父类的有参构造方法
- this( ) super( )必须放在构造方法的第一行有效语句,所以二者不能共存。
4. 抽象类
将共性的方法抽取到父类后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法即可以定义为抽象方法。
如果一个类中存在抽象方法,那么该类就必须定义为一个抽象类。
注意事项:
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能实例化
- 抽象类可以有构造方法
- 抽象类的子类,要么重写抽象类中的所有抽象方法,要么定义为一个抽象类
模板设计模式:把抽象类整体看做成一个模板,把模板中不能决定的功能定义成抽象方法,让使用模板的类去重写抽象方法实现需求。模板已经定义了通用结构,使用者只需要关心自己需要实现的功能即可。
5. final关键字
final代表最终的意思,可以修饰成员方法,成员变量和类。
final修饰类、方法、变量的效果:
- fianl修饰类:该类不能被继承。(不能有子类,但是可以有父类)
- final修饰方法:该方法不能被重写。
- final修饰变量:表明该变量是一个常量,不能再次赋值,若变量是引用类型,则不能改变的是地址值,但地址里面的内容是可以改变的。
6. 代码块 {}
局部代码块:
- 位置: 方法中定义
- 作用: 限定变量的生命周期,及早释放,提高内存利用率
构造代码块:
- 位置: 类中方法外定义
- 特点: 每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行
- 作用: 将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性
静态代码块:
- 位置: 类中方法外定义
- 特点: 需要通过static关键字修饰,随着类的加载而加载,并且只执行一次
- 作用: 在类加载的时候做一些数据初始化的操作
7. 优化信息管理系统
- 把学生类和老师类共性的内容向上抽取,抽取到出一个 Person 父类,让学生类和老师类继承 Person 类。
- 开闭原则:对扩展内容开放,对修改内容关闭 。对于需要修改的代码逻辑不在本类中修改,复制一份重命名后再修改。保留一份代码是以防用户需求不断改变。
- 修改后的两份代码大部分是相同的,又可以抽取一个父类让两份代码继承父类,不同之处只需要重写父类方法即可。
- 将不希望子类重写的方法,使用 final 进行修饰
- 使用静态代码块,初始化一些学生数据
(具体实现代码在我的资料中,信息管理系统 v3.0)
如有错误请留言评论,及时更正。 5月23日 羽露风