当我们在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了!
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类!
抽象类和抽象方法必须使用 abstract 关键字修饰
xxxxxxxxxx
//抽象类的定义
public abstract class 类名 {}
//抽象方法的定义
public abstract void eat();
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能实例化
抽象类可以有构造方法
抽象类的子类
要么重写抽象类中的所有抽象方法
要么是抽象类
案例需求
定义猫类(Cat)和狗类(Dog)
猫类成员方法:eat(猫吃鱼)drink(喝水…)
狗类成员方法:eat(狗吃肉)drink(喝水…)
实现步骤
代码实现
xxxxxxxxxx
public abstract class Animal {
public void drink(){
System.out.println("喝水");
}
public Animal(){
}
public abstract void eat();
}
xxxxxxxxxx
public class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
xxxxxxxxxx
public class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
}
xxxxxxxxxx
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
d.drink();
Cat c = new Cat();
c.drink();
c.eat();
//Animal a = new Animal();
//a.eat();
}
设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
模板设计模式
把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法 让使用模板的类(继承抽象类的类)去重写抽象方法实现需求
模板设计模式的优势
模板已经定义了通用结构,使用者只需要关心自己需要实现的功能即可
示例代码
模板类
xxxxxxxxxx
/*
作文模板类
*/
public abstract class CompositionTemplate {
public final void write(){
System.out.println("<<我的爸爸>>");
body();
System.out.println("啊~ 这就是我的爸爸");
}
public abstract void body();
}
实现类A
xxxxxxxxxx
public class Tom extends CompositionTemplate {
public void body() {
System.out.println("那是一个秋天, 风儿那么缠绵,记忆中, " +
"那天爸爸骑车接我放学回家,我的脚卡在了自行车链当中, 爸爸蹬不动,他就站起来蹬...");
}
}
实现类B
xxxxxxxxxx
public class Tony extends CompositionTemplate {
public void body() {
}
/*public void write(){
}*/
}
测试类
xxxxxxxxxx
public class Test {
public static void main(String[] args) {
Tom t = new Tom();
t.write();
}
}
fianl关键字的作用
final修饰类、方法、变量的效果
fianl修饰类:该类不能被继承(不能有子类,但是可以有父类)
final修饰方法:该方法不能被重写
final修饰变量:表明该变量是一个常量,不能再次赋值
变量是基本类型,不能改变的是值
变量是引用类型,不能改变的是地址值,但地址里面的内容是可以改变的
举例
xxxxxxxxxx
public static void main(String[] args){
final Student s = new Student(23);
s = new Student(24); // 错误
s.setAge(24); // 正确
}
需求
代码实现
BaseStudentController类
xxxxxxxxxx
public abstract class BaseStudentController {
// 业务员对象
private StudentService studentService = new StudentService();
private Scanner sc = new Scanner(System.in);
// 开启学生管理系统, 并展示学生管理系统菜单
public final void start() {
//Scanner sc = new Scanner(System.in);
studentLoop:
while (true) {
System.out.println("--------欢迎来到 <学生> 管理系统--------");
System.out.println("请输入您的选择: 1.添加学生 2.删除学生 3.修改学生 4.查看学生 5.退出");
String choice = sc.next();
switch (choice) {
case "1":
// System.out.println("添加");
addStudent();
break;
case "2":
// System.out.println("删除");
deleteStudentById();
break;
case "3":
// System.out.println("修改");
updateStudent();
break;
case "4":
// System.out.println("查询");
findAllStudent();
break;
case "5":
System.out.println("感谢您使用学生管理系统, 再见!");
break studentLoop;
default:
System.out.println("您的输入有误, 请重新输入");
break;
}
}
}
// 修改学生方法
public final void updateStudent() {
String updateId = inputStudentId();
Student newStu = inputStudentInfo(updateId);
studentService.updateStudent(updateId, newStu);
System.out.println("修改成功!");
}
// 删除学生方法
public final void deleteStudentById() {
String delId = inputStudentId();
// 3. 调用业务员中的deleteStudentById根据id, 删除学生
studentService.deleteStudentById(delId);
// 4. 提示删除成功
System.out.println("删除成功!");
}
// 查看学生方法
public final void findAllStudent() {
// 1. 调用业务员中的获取方法, 得到学生的对象数组
Student[] stus = studentService.findAllStudent();
// 2. 判断数组的内存地址, 是否为null
if (stus == null) {
System.out.println("查无信息, 请添加后重试");
return;
}
// 3. 遍历数组, 获取学生信息并打印在控制台
System.out.println("学号\t\t姓名\t年龄\t生日");
for (int i = 0; i < stus.length; i++) {
Student stu = stus[i];
if (stu != null) {
System.out.println(stu.getId() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getBirthday());
}
}
}
// 添加学生方法
public final void addStudent() {
// StudentService studentService = new StudentService();
// 1. 键盘接收学生信息
String id;
while (true) {
System.out.println("请输入学生id:");
id = sc.next();
boolean flag = studentService.isExists(id);
if (flag) {
System.out.println("学号已被占用, 请重新输入");
} else {
break;
}
}
Student stu = inputStudentInfo(id);
// 3. 将学生对象,传递给StudentService(业务员)中的addStudent方法
boolean result = studentService.addStudent(stu);
// 4. 根据返回的boolean类型结果, 在控制台打印成功\失败
if (result) {
System.out.println("添加成功");
} else {
System.out.println("添加失败");
}
}
// 键盘录入学生id
public String inputStudentId() {
String id;
while (true) {
System.out.println("请输入学生id:");
id = sc.next();
boolean exists = studentService.isExists(id);
if (!exists) {
System.out.println("您输入的id不存在, 请重新输入:");
} else {
break;
}
}
return id;
}
// 键盘录入学生信息
// 开闭原则: 对扩展内容开放, 对修改内容关闭
public abstract Student inputStudentInfo(String id);
}