3.定义普通人、老师、班主任、学生、学校这些类,提供适当的成员变量、方法用于描述其内部数据和行为特征,并提供主类使之运行。要求有良好的封装性,将不同类放在不同的包下面,增加文档注释,生成API文档。
人类,用来继承的抽象类,不能创造实例
发现重写了OrdinaryPerson的equals后,他的子类其实就不用再重写equals了。
package people;
/**
* 定义成抽象方法,只能继承不能创建实例
* 这是一个人类,是一个抽象的类,因为不存在人类,它只是一种概念
* 所以不能创建实例,所以就弄成了抽象类,又由于其子类并不一定要继承其他的类
* 所以就不定义成接口了,也没有一定要子类重写的方法,所以就不提供抽象方法了。
* @author 程序代号
* @version 1.0
*/
public abstract class Person
{
//类变量
private static int eyes_num = 2;//每个人只有两个眼睛,不会变
//成员变量, 我不希望除了本类以外内部以外,还有其他的类能够访问,
//即使是通过调用本类的实例直接访问,只能通过我提供的方法来访问
//只能用提供的方法访问的目的是,能够在方法里面进行一些检查,防止不合理的
// 值被设置,比如一个人有30000岁,很明显,不可能,
private String name,gender;
private int age;
//默认构造器
public Person(){}
//构造器1
public Person(String name)
{
this.name = name;
}
//重载构造器
public Person(String name, int age)
{
this(name);
this.age = age;
}
//再次重载构造器
public Person(String name,int age, String gender)
{
this(name, age);
this.gender = gender;
}
/**
* 干饭方法
* @param thing 吃的东西的名称
*/
protected void eat(String thing)
{
System.out.println(name+"正在吃"+thing);
}
/**
* 喝水方法
* @param thing 喝的饮料名称
*/
protected void drink(String thing)
{
System.out.println(name+"正在喝"+thing);
}
/**
* 玩的方法
* @param thing 玩的东西的名称
*/
protected void play(String thing)
{
System.out.println(name + "正在玩" + thing);
}
/**
* 睡觉方法
*/
protected void sleep()
{
System.out.println(name +"正在睡觉");
}
//setter和getter方法
/**
* name的set方法
* @param name 人的名字
*/
public void setName(String name)
{
this.name = name;
}
/**
* name的get方法
* @return 姓名
*/
public String getName()
{
return name;
}
/**
* age的set方法
* @param age 人的年龄
*/
public void setAge(int age)
{
this.age = age;
}
/**
* age的get方法
* @return 年龄
*/
public int getAge()
{
return age;
}
/**
* gender的set方法
* @param gender 人的性别
*/
public void setGender(String gender)
{
this.gender = gender;
}
/**
* gender的get方法
* @return 性别
*/
public String getGender()
{
return gender;
}
}
普通人类,继承了人类
package people;
/**
* 普通人,这个类是一个普通人的一个类,
* 没有什么特殊的地方,
* 有一个普通的跑步的方法
* 有一个普通的笑的方法
* @author 程序代号
* @version 1.0
*/
class OrdinaryPerson extends Person
{
public OrdinaryPerson(){}//默认构造器
//居然不能直接用Person的构造器
public OrdinaryPerson(String name,int age,String gender)
{
super(name, age, gender);
}
/**
* 普通的跑步
*/
protected void run()
{
System.out.println(getName() + "普通的跑步");
}
/**
* 普通的笑
*/
protected void laugh()
{
System.out.println(getName()+"普通的笑");
}
public String toString()
{
return "普通人姓名:"+getName()+
"\n普通人年龄:"+getAge()+
"\n普通人性别:"+getGender();
}
//重写equals方法
public boolean equals(Object obj)
{
//先看看是不是和指向同一个对象
if(this == obj)
return true;
//如果不为null ,并且是同一个类的实例
if( obj != null && obj.getClass() == OrdinaryPerson.class)
{
//并且name相同
//先强制类型转换
var ordinaryPerson = (OrdinaryPerson) obj;
//并且姓名相同
if(this.getName().equals(ordinaryPerson.getName()))
{
return true;
}
}
return false;
}
}
Teacher类
在写这个类的过程中,我发现子类居然不能自己写父类没有的构造器
比如Teacher类写了一个默认的空构造器,而父类OrdinaryPerson并没有写这个构造器,就会导致报错
package people;
/**
* 老师,因为老师其实也是一个普通人,所以就
* 继承了普通人类,
* @author 程序代号
* @version 1.0
*/
public class Teacher extends OrdinaryPerson
{
//成员变量
private String subject; // 教授的科目
//因为子类并不会继承父类的构造器,所以需要重写一下
//不知道能不能直接用爷爷类的,不能
//再提供一个默认的构造器
public Teacher(){}
public Teacher(String name, int age, String gender,String subject)
{
super(name,age, gender);
this.subject = subject;
}
/**
* 上课方法
*/
public void teach()
{
System.out.println(getName() + "正在教学生"+subject);
}
/**
* subject的set方法
* @param subject 老师教学的科目
*/
public void setSubject(String subject)
{
this.subject = subject;
}
/**
* subject的get方法
*/
public String getSubject()
{
return subject;
}
public String toString()
{
return "老师姓名:"+getName()+
"\n老师年龄:"+getAge()+
"\n老师性别:"+getGender()+
"\n老师教授的科目:"+getSubject();
}
public boolean equals(Object obj)
{
if(this == obj)
{
return true;
}
if(obj != null && obj.getClass() == Teacher.class)//如果他们的name相同就认为是同一个对象
{
Teacher teacher = (Teacher) obj;
if(this.getName().equals(teacher.getName()))
{
return true;
}
}
return false;
}
}
班主任类
package people;
/**
* 班主任,他虽然是班主任,但同时也会是一名老师
* @author 程序代号
* @version 1.0
*/
public class HeadMaster extends Teacher
{
public String classroom; // 是哪个班级的
//提供一个默认构造器
public HeadMaster(){}
public HeadMaster(String name , int age, String gender,String subject, String classroom)
{
super(name,age, gender, subject);
this.classroom = classroom;
}
/**
* 班主任嘛,总有一个监督的方法
*/
public void check()
{
System.out.println(getName()+"班主任正在监督"+classroom);
}
/**
* classroom的set方法
* @param classroom 班主任监督的是哪个班级
*/
public void setClassRoom(String classroom)
{
this.classroom = classroom;
}
/**
* classroom的get方法
* @return 班级的名称
*/
public String getClassRoom()
{
return classroom;
}
}
学生类
package people;
/**
* 学生类,因为学生也是普通人,所以就继承了普通人类
* @author 程序代号
* @version 1.0
*/
public class Student1 extends OrdinaryPerson
{
private String number;//学生嘛,肯定会有学号的
//默认构造器
public Student1(){}
//
public Student1(String name, int age , String gender, String number)
{
super(name, age, gender);
this.number = number;
}
/**
* 学生嘛,肯定要有读书的方法
* @param title
*/
public void read(String title)
{
System.out.println(getName()+"正在读"+title);
}
/**
* number 学号的set方法
* @param number 学生的学号
*/
public void setNumber(String number)
{
this.number = number;
}
/**
* number学号的get方法
* @return 学号
*/
public String getNumber()
{
return number;
}
}
学校类
这里其实可以用组合的方法,把老师和学生组合进来
package build;
/**
* 学校类,一个神奇的建筑,孕育着无数的怀揣梦想的人
* @author 程序代号
* @version 1.0
*/
public class School
{
//没有继承任何的类,所以默认继承Object类
//成员变量
private int year;
private String name;
private int size;
//默认构造器
public School(){}
public School(int year, String name, int size)
{
this.year = year;
this.name = name;
this.size = size;
}
//一些方法
/**
* 开启方法,学校总是会在早上开门
*/
public void open()
{
System.out.println(name+"学校向你敞开了大门");
}
/**
* 关门方法,学校总是会在晚上关门
*/
public void close()
{
System.out.println("夜深了,"+name+"关闭了大门");
}
//set和get方法
/**
* year的set方法
* @param year 学校的建成年份
*/
public void setYear(int year)
{
this.year =year;
}
/**
* year的get方法
* @return 学习建成年份
*/
public int getYear()
{
return year;
}
/**
* name的set方法
* @param name 学校的名称
*/
public void setName(String name)
{
this.name = name;
}
/**
* name的get方法
* @return 学校名称
*/
public String getName()
{
return name;
}
/**
* size的set方法
* @param size 学校的规模,也就是总人数
*/
public void setSize(int size)
{
this.size = size;
}
/**
* size的get方法
* @return 学校的人数
*/
public int getSize()
{
return size;
}
}
运行用的主类
package people;
import build.*;
/**
* 程序运行用的主类,也可以叫做入口类,
* 一些类在这里被创建,一些方法,在这里被调用
* @author 程序代号
* @version 1.0
*/
public class Main
{
public static void main(String[] args)
{
//尝试创建抽象类的实例
//Person person = new Person("小王", 15 , "男");
//创建一个普通人,并调用他从人类那里继承的方法和构造器
OrdinaryPerson op = new OrdinaryPerson("小王",300,"男");
op.play("小猪佩奇");
op.run();
op.eat("面包");
op.drink("牛奶");
System.out.println(op.toString());
//再创建一个老师类
Teacher teacher = new Teacher("老李",2000,"女","美术");
teacher.teach();
teacher.run();
teacher.laugh();
teacher.eat("红薯");
System.out.println(teacher.toString());
//创建一个班主任类
HeadMaster hm = new HeadMaster("林柳", 3000,"男", "语文","3年2班");
hm.eat("炸鸡");
hm.check();
hm.run();
System.out.println(hm.toString());
//创建一个学生类
Student1 student = new Student1("王二麻子", 20000,"女","1234567");
student.run();
student.read("九阴真经");
System.out.println(student.toString());
//创建一个学校类
School school = new School(1888,"修仙研究学院",820);
school.open();
school.close();
System.out.println(school.toString());
//比较两个ordinaryperson是否相等
OrdinaryPerson op1 = new OrdinaryPerson("小王",200,"男");
System.out.println(op.equals(op1));
OrdinaryPerson op2 = new OrdinaryPerson("小李",299,"女");
System.out.println("小王和小李是否是同一个人:"+op1.equals(op2));
System.out.println("小王和小王是否是同一个人:"+op1.equals(op1));
//比较两个Teacher
Teacher t1 = new Teacher("刘彤",100,"女", "数学");
Teacher t2 = new Teacher("溜溜", 200, "男", "英语");
System.out.println("刘彤是否和溜溜相等"+t1.equals(t2));
System.out.println("溜溜是否和溜溜相等"+t2.equals(t2));
//比较两个班主任
HeadMaster h1 = new HeadMaster("往往",100,"男","语文","5年7班");
HeadMaster h2 = new HeadMaster("牛牛",200,"女", "考古", "8年9班");
System.out.println("往往是否和牛牛是同一个人:"+h1.equals(h2));
System.out.println("牛牛是否和牛牛是同一个人:"+h2.equals(h2));
}
}