抽象类以及模板方法设计模式,接口(@Data使用方法,综合小案例)
·
面向对象高级
抽象类

抽象类的注意事项、特点

抽象类的核心特点:有得有失(得到了抽象方法的能力,失去了创建对象的能力)。抽象类不能创建对象;
抽象类的使命就是被子类继承,就是为了生孩子;
一个类继承抽象类,必须重写完继承的全部抽象方法,否则这个类也不许定义成抽象类
抽象类认识小结

使用抽象类的好处

package com.itheima.abstarct2;
public class Test {
public static void main(String[] args) {
//目标:搞清楚使用抽象类的好处
Animal a1 = new Cat();
a1.cry();
}
}
//=================分界线=================
package com.itheima.abstarct2;
public abstract class Animal {
//描述每个动物的叫声
public abstract void cry();//父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现
}
//=================分界线=================
package com.itheima.abstarct2;
public class Cat extends Animal{
@Override
public void cry() {
System.out.println("小猫喵喵叫");
}
}
//=================分界线=================
package com.itheima.abstarct2;
public class Dog extends Animal{
@Override
public void cry() {
System.out.println("汪汪汪");
}
}
ps:抽象类在编写代码时不是必须的,只是使用起来会更方便
模板方法设计模式



ps:在句子中的作用相当于开头结尾一样,中间使用抽象类调用不同子类实现不同情况
package com.itheima.abstract3;
public class Test {
public static void main(String[] args) {
//目标:理解抽象类的使用场景:模板方法设计模式
//学生和老师都要写一篇作文:《我的自己》
// 第一段一样:我是一个有毅力的人
// 第二段不一样,各自写各自的
// 第三段一样:我的自己是不一样的自己
//解决:抽出一个父类,父类中还抽取一个模板方法给子类直接用
Student s1 = new Student();
s1.write();
Teacher t1 = new Teacher();
t1.write();
}
}
//=================分界线=================
package com.itheima.abstract3;
public abstract class People {
//1.模板方法设计模式(建议使用final修饰模板方法,使其不失效)
public final void write(){
System.out.println("\t\t\t《我的自己》");
System.out.println("我是一个有毅力的人");
writeMain();//2.模板方法知道子类一定要写这个正文,但是每个子类写的信息是不同的,父类定义一个抽象方法,具体的实现交给子类来重写给正文
System.out.println("我的自己是不一样的自己");
}
public abstract void writeMain();
}
//=================分界线=================
package com.itheima.abstract3;
public class Student extends People{
@Override
public void writeMain() {
System.out.println("我是一个老师,我是一个自己");
}
// public void write(){
// System.out.println("\t\t\t《我的自己》");
// System.out.println("我是一个有毅力的人");
// System.out.println("我的自己是不一样的自己");
// System.out.println("我的自己是不一样的自己");
// }
}
//=================分界线=================
package com.itheima.abstract3;
public class Teacher extends People{
@Override
public void writeMain() {
System.out.println("我是一个学生,我是一个自己");
}
}
模板方法设计模式小结

接口

ps:
- JDK8之前接口内只能定义常量和抽象方法;
- 接口中定义常量(复习:使用static public修饰的成员变量就被称为常量。前提理解:常量必须初始化赋值,否则会报错,且命名用大写字母表示)可以省略public static final不写,默认会加上;
- 接口中定义抽象方法可以省略public static 不写,默认会加上;
- 接口不能创建对象(接口是用来被实现的)

ps:
- 实现类可以实现多个接口,相当于可以有多个干爹(接口),但是亲爹(父类)只能有一个
- 实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类必须定义成抽象类
接口好处

package com.itheima.interface2;
public class Test {
public static void main(String[] args) {
//目标:去理解java设计接口的好处,用处
//接口弥补了类单继承的不足,可以让类拥有更多角色(继承了更多接口的功能),类的功能更强大
Student p = new Student();
Driver d = new Student();//多态
BoyFriend bf = new Student();
//接口可以实现面向接口编程,更利于解耦合(子父类是 多子---一父 ,接口是 多实现类---多接口)
Driver a1 = new Student();
Driver a2 = new Teacher();
BoyFriend a3 = new Student();
}
}
interface Driver{}
interface BoyFriend{}
class People{}
class Student extends People implements Driver,BoyFriend{}
class Teacher implements Driver,BoyFriend{}
接口的综合小案例

接口只是提供一套方法,具体实现要交给实现类
package interface3;
public class Test {
public static void main(String[] args) {
//目标:完成接口的小案例
//1.定义学生类,创建学生对象,封装学生数据,才能交给别人处理学生的数据
//2.准备学生数据,目前我们自己造一些测试数据
Student[] allStudents = new Student[10];
allStudents[0] = new Student("小王",'男',90.5);
allStudents[1] = new Student("小张",'女',80.5);
allStudents[2] = new Student("小李",'男',70.5);
allStudents[3] = new Student("小赵",'女',60.5);
allStudents[4] = new Student("小钱",'男',50.5);
allStudents[5] = new Student("小孙",'女',40.5);
allStudents[6] = new Student("小李",'男',30.5);
allStudents[7] = new Student("小王",'女',20.5);
allStudents[8] = new Student("小赵",'男',10.5);
allStudents[9] = new Student("小钱",'女',0.5);
//3.提供两套业务实现方案,支持林火切换(解耦合),面向接口编程
// --定义一个接口(规范思想),必须完成打印全班学生信息,打印平均分
// --定义第一套实现类,实现接口,实现打印信息,实现打印平均分
// --定义第二套实现类,实现接口,实现打印信息(男女人数),实现打印平均分(去掉最高分和最低分)
ClassDataInter cdi = new ClassDataInterImpl2(allStudents);//(接口多态)可以切换实现类的一二,体现解耦思想
cdi.printAllStudents();
cdi.printAvgScore();
}
}
//=================分界线=================
package interface3;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data//使用方法,输入@Data等待报错后鼠标点击然后Alt+Enter快捷键,回车回车,添加无参构造器
@AllArgsConstructor//添加有参构造器,但是无参构造器又没了
@NoArgsConstructor//再次添加无参构造器
public class Student {
private String name;
private char sex;
private double score;
}
//=================分界线=================
package interface3;
//接口只是提供一套方法,具体实现要交给实现类
public interface ClassDataInter {
void printAllStudents();
void printAvgScore();
}
package interface3;
//快捷重写接口里的方法,鼠标在接口名上然后Alt+Enter+回车回车
public class ClassDataInterImpl1 implements ClassDataInter{
private Student[] Students;//记住送来的全班学生对象信息
public ClassDataInterImpl1(Student[] Students)//实参 → 形参(参数传递) 形参 → 实例变量(赋值操作)
{
this.Students = Students;
}
@Override
public void printAllStudents() {
System.out.println("全班学生信息如下:");
for (int i = 0; i < Students.length; i++) {
Student s = Students[i];
System.out.println(Students[i]);
System.out.println("姓名:" + s.getName() + ",性别:" + s.getSex() + ",成绩:" + s.getScore());
}
}
@Override
public void printAvgScore() {
double sum = 0;
for (int i = 0; i < Students.length; i++) {
Student s = Students[i];
sum += s.getScore();
}
System.out.println("全班平均分是:" + sum / Students.length);
}
}
//=================分界线=================
package interface3;
//快捷重写接口里的方法,鼠标在接口名上然后Alt+Enter+回车回车
public class ClassDataInterImpl2 implements ClassDataInter{
private Student[] Students;//记住送来的全班学生对象信息
public ClassDataInterImpl2(Student[] Students)
{
this.Students = Students;
}
@Override
public void printAllStudents() {
int maleCount = 0;
for (int i = 0; i < Students.length; i++) {
Student s = Students[i];
System.out.println("姓名:" + s.getName() + ",性别:" + s.getSex() + ",成绩:" + s.getScore());
if(s.getSex() == '男')
maleCount++;
}
System.out.println("全班男性人数是:" + maleCount);
System.out.println(Students.length - maleCount);
}
@Override
public void printAvgScore() {
System.out.println("全班平均分是:" );
Student s1 = Students[0];
double sum = s1.getScore();
double max = s1.getScore();
double min = s1.getScore();
for (int i = 1; i < Students.length; i++) {
Student s = Students[i];
sum += s.getScore();
if(s.getScore() > max)
max = s.getScore();
if(s.getScore() < min)
min = s.getScore();
}
System.out.println("全班平均分是:" + (sum - max - min ) / Students.length);
System.out.println("全班最高分是:" + max);
System.out.println("全班最低分是:" + min);
}
}
更多推荐


所有评论(0)