抽象类:
abstract,可以用此关键字修饰类和方法
abstract修饰类就是抽象类,修饰方法就是抽象方法
抽象类的注意事项,特点:
抽象类不一定有抽象方法,但有抽象方法的类一定是抽象类类该有的成员(成员变量,方法,构造器)抽象类也可以有
抽象类的特点:抽象类不能创建对象,仅仅作为一种特殊的父类,让子类继承并实现
一个类继承抽象类,必须重写抽象类的全部抽象方法,否则这个类也变成抽象类
测试:
public class test {
public static void main(String[] args) {
animal a1=new cat();
animal a2=new dog();
a1.bark();
a2.bark();
animal[]a=new animal[]{new cat("hh"),new dog("aa")};
for(int i=0;i<a.length;i++)
{
a[i].bark();
}
}
}
结果:
模板方法设计模式的写法:
- 1:定义一个抽象类
- 2:在类里面定义两个方法:
一个是模板方法:把相同代码放到里面去
一个是抽象方法:具体实现交给子类完成
建议在模板方法用final修饰,防止被子类重写
接口:
public inferface 接口名(类似干爹)
{
//成员变量(当作常量)
//成员方法(当作抽象方法)
}
注意:接口不能创建对象;接口是用来被类实现的,实现接口的类叫实现类
修饰符 class 实现类 implements 接口1,接口2...
{}
一个类可以实现多个接口,必须重写所有接口的抽象方法
接口的好处:
弥补了类单继承的不足,一个类可以实现多个接口。
让程序员可以面向接口编程。
使用接口:
这是我写的一个学生管理系统,里面有两种管理方法,可以使用一种接口类和两种实现类
学生类:
public class student {
private String name;
private String sex;
private double score;
public student() {
}
public student(String name, String sex, double score) {
this.name = name;
this.sex = sex;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
这是接口类:
public interface operator {
void printIN(ArrayList<student>list);
void printAv(ArrayList<student>list);
}
里面的这两个函数都是抽象函数
我们可以定义两种实现类,实现多态。
第一个实现类
public class operatorimp1 implements operator{
@Override
public void printIN(ArrayList<student> list) {
System.out.println("----所有学生信息如下----");
for(int i=0;i<list.size();i++)
{
student s=list.get(i);
System.out.println("姓名:"+s.getName()+",性别:"+s.getSex()+",分数"+s.getScore());
}
}
@Override
public void printAv(ArrayList<student> list) {
double scoreAll=0.0;
for (int i = 0; i < list.size(); i++) {
student s=list.get(i);
scoreAll+=s.getScore();
}
System.out.println("----所有学生平均成绩如下------");
System.out.println("平均成绩为:"+(scoreAll/ list.size()));
}
}
第二个实现类:
public class operatorimp2 implements operator {
@Override
public void printIN(ArrayList<student> list) {
int count1=0;//记录男生数量
int count2=0;//记录女生数量
System.out.println("----所有学生信息如下----");
for (int i = 0; i < list.size(); i++) {
student s = list.get(i);
System.out.println("姓名:" + s.getName() + ",性别:" + s.getSex() + ",分数" + s.getScore());
if(s.getSex().equals("男"))
{
count1++;
}
else count2++;
}
System.out.println("男生数量为:"+count1+",女生数量为:"+count2);
}
@Override
public void printAv(ArrayList<student> list) {
double scoreAll = 0.0;
int maxindex=0;
int minindex=0;
for (int i = 0; i < list.size(); i++) {
if(list.get(i).getScore()>list.get(maxindex).getScore())
{
maxindex=i;
}
if(list.get(i).getScore()<list.get(minindex).getScore())
{
minindex=i;
}
student s = list.get(i);
scoreAll += s.getScore();
}
System.out.println("----所有学生平均成绩如下------");
System.out.println("最高分为:"+list.get(maxindex).getScore()+",最低分为:"+list.get(minindex).getScore());
System.out.println("平均成绩为:" + ((scoreAll-list.get(maxindex).getScore()-list.get(minindex).getScore()) / (list.size()-2)));
}
}
这样一来我们就可以定义两个两个学生管理类
接下来我定义了一个添加学生的类
import java.util.ArrayList;
import java.util.Scanner;
public class studentAdd {
static ArrayList<student> list = new ArrayList<>();
static Scanner sa = new Scanner(System.in);
public studentAdd() {
}
public static ArrayList<student> studentadd() {
System.out.println("请输入学生姓名");
student s = new student();
s.setName(sa.next());
System.out.println("请输入学生性别");
s.setSex(sa.next());
System.out.println("请输入学生成绩");
s.setScore(sa.nextDouble());
System.out.println("录入成功");
System.out.println("------该学生的信息如下-----");
System.out.println("姓名:"+s.getName()+",性别:"+s.getSex()+",分数:"+s.getScore());
list.add(s);
return list;
}
}
最后就是总类:
import java.util.ArrayList;
import java.util.Scanner;
public class studentStart {
Scanner sa1=new Scanner(System.in);
Scanner sa2=new Scanner(System.in);
ArrayList<student> list=new ArrayList<>();
public void studentstart() {
while (true) {
System.out.println("-----欢迎进入学生管理系统------");
System.out.println("按1进入添加学生功能");
System.out.println("按2进入管理学生信息系统1");
System.out.println("按3进入管理学生信息系统2");
System.out.println("按4退出学生管理系统");
int i = sa1.nextInt();
if (i == 1) {
list=studentAdd.studentadd();//添加新学生
}
if(i==2)
{
while (true) {
System.out.println("-----欢迎进入学生信息系统1------");
System.out.println("按1打印所有学生信息");
System.out.println("按2打印学生平均成绩");
System.out.println("按3退出学生信息系统1");
studentManger1 m1=new studentManger1(list);//把list传入
int x=sa2.nextInt();
if(x==1)
{
m1.printINFO();
}
if(x==2)
{
m1.printAve();
}
if(x==3)
{
System.out.println("退出学生信息系统1,欢迎下次光临~~");
break;
}
}
}
if(i==3)
{
while (true) {
System.out.println("-----欢迎进入学生信息系统2------");
System.out.println("按1打印所有学生信息");
System.out.println("按2打印学生平均成绩");
System.out.println("按3退出学生信息系统2");
studentManger2 m2=new studentManger2(list);
int x=sa2.nextInt();
if(x==1)
{
m2.printINFO();
}
if(x==2)
{
m2.printAve();
}
if(x==3)
{
System.out.println("退出学生信息系统2,欢迎下次光临~~");
break;
}
}
}
if(i==4)
{
System.out.println("退出学生管理系统,欢迎下次光临~~");
break;
}
}
}
}
测试:
public class test {
public static void main(String[] args) {
/*studentAdd add1=new studentAdd();
ArrayList<student>list=new ArrayList<>();
list=add1.studentadd();
list=add1.studentadd();
studentManger1 m1=new studentManger1(list);
m1.printINFO();
m1.printAve();*/
studentStart s=new studentStart();
s.studentstart();
}
}
结果:
添加功能:
进入信息管理系统1:
进入信息管理系统2:
接口新增方法:
默认方法:使用default修饰,使用实现类的对象调用
接口类 对象=new 实现类();
静态方法:static修饰,必须使用当前接口名调用
私有方法:private修饰,只有在接口内部被调用
以上三种都不是抽象方法,他们都会默认被public修饰
好处:增强接口的能力,更便于项目的扩展和维护。
接口的多继承:
一个接口可以同时继承多个接口
便于实现类的实现
注意事项:
- 一个接口继承多个接口,如果多个接口中存在方法签名(名字一样,不管类型)冲突,则此时不支持多继承。
- yige一个类实现多个接口,如果多个接口存在方法签名冲突,则此时不支持多实现
- 一个类继承了父类,又同时实现了接口,父类和接口中有同名的默认方法(default修饰),实现类会优先调用父类的
- yige一个类实现多个接口,多个接口存在同名的默认方法,可以不冲突,这个类重写该方法即可