目录
1. 笔记
1.1 抽象类
1.抽象类☆ 前提:Animal(父类)所有的子类都对eat方法进行了重写。Animal是为子类提供服务。 Animal类中的eat方法,大括号还有用吗?没有用了。 将eat方法变为抽象方法 ①使用abstract修饰符修饰方法 ②将大括号删除,分号结尾 将类变为抽象类 ①使用abstract修饰符修饰类 特点: ①抽象方法存在的类,必须是抽象类! ②子类继承抽象类时,必须实现抽类中所有的抽象方法 重写:父类有方法体,子类覆盖父类的方法体 实现:父类没有方法体,子类第一次指定方法体 ③抽象类中可以由0-n个抽象方法或普通方法 ④如果子类不能够实现抽象类中的抽象方法? 那么子类也必须变为抽象类 ⑤抽象类是不能够实例化对象的! ⑥抽象类有构造器吗?有的! 抽象类不能够实例化对象,抽象类的使用必须是父类了! 所以构造器就是初始化子类对象的父类空间的 应用:一般作为模板工具类 模板:一部分是确定的,一部分是不确定的 2.权限修饰符 本类 本包 其他包(子类) 其他包(非子类) public √ √ √ √ protected √ √ √ × 缺省的 √ √ × × private √ × × ×
1.2 多态
1.多态★ 面向对象的三大特性之一 1.1定义 是指同一行为,具有多个不同表现形式(重载和重写) 1.2前提 ①父子类 ②必须有重写 ③父类引用指向子类对象 1.3 多态的语法 父类引用指向子类对象 举例:Person per1 = new Employee(); per1.eat(); //从名义上是调用Person类的eat方法,但是实际上是员工餐 1.4 多态的注意事项 使用不了子类独有的内容 因为名义上是父类类型,就只能调用到父类中存在的,如果子类有重写 这个是可以调用到子类的方法的,如果没有重写就是父类的 总结:多态只能调用父类的内容 成员变量: 子类独有的访问不到,如果有重名属性,调用属性看类型。 1.5 多态的用途 ①多态数组★ ②多态数组 -> 对象数组的升级 2. 父子类之间的类型转换 2.1 自动转换(向上转型-多态的体现) 小-大 2.2 强制转换(向下转型) 大-小 因为多态,调用不到子类独有的内容!我就是想调用(很少见) 向下转型是有风险!所以以后能少强转就少强转! 语法:子类类型 对象名=(子类类型)父类引用; 强转之前一定要做判断! instanceof 判断前面的对象是否属于后面的类型 举例: boolean flag = employee instanceof Employeel;
1.3 native关键字
1. native 本地的 原生的 只能修饰方法 追踪源码的时侯,回见到这个关键字。方法不是java实现,是c语言实现 native修饰的方法,是可以被重写的 1.1 不能和abstract一起使用的修饰符? (1)final:和final不能一起修饰方法和类 (2)static:和static不能一起修饰方法 (3)native:和native不能一起修饰方法 记住 (4)private: 和private不能一起修饰方法 1.2 static和final一起使用: (1)修饰方法:可以,因为都不能被重写 (2)修饰成员变量:可以,表示静态常量 (3)修饰代码块:不可以,final不能修饰代码块 (4)修饰局部变量:不可以,static不能修饰局部变量 (5)修饰内部类:可以一起修饰成员内部类,不能一起修饰局部内部类
1.4 根父类(Object)
1. Object 根父类 默认是类的父类! 该类中所有的方法都可以被任意对象继承下去。 根据api去学。 构造器: Object(); 方法: ① toString(); public String toString(){ return getClass().getName()+"@"+Integer.toHexString(hashCode()); } ② Class getClass(); 反射位置,会遇到次方法! 功能:返回对象的运行时类型(类加载的时候,会创建一个Class对象) ③ int hashCode(); 将当前对象,通过哈希算法,得到一个int值 两对相同对象(地址一样的):经过相同的hash算法,得到的int值肯定是 一样的。 两个不同的对象:经过相同的hash算法,得到int值,也有可能一样, 大概率是不一样的 集合-->HashMap集合的时候,会遇到hashCode方法。 ④ finalize() java存在垃圾回收机制的(自动的机制) java中什么样的对象,会被认为是垃圾? 没有引用的对象 java中被认为是垃圾的对象,什么时候会被来及回收机制回收? 不定时回收 垃圾对象被回收的时候,实惠默认调用该对象的finalize方法 目的:是让这个对象做一个临终遗言(这个方法不是回收的代码) ⑤ equals(Object obj) 判断两个对象是否一致 == 主要是判断两个地址是否一致 源码: 和==没有区别 public boolean equals(Object obj){ return(this == obj); } 2. String类的equals方法 两个对象,this/anObject对比内容是否一致 自我练习: 创建两个person对象,我认为,只要name和id都一样,就是同一个人 在Person类中,重写equals方法(对比内容,id和name)
2. 练习
2.1 抽象类练习
练习一:定义一个几何图形父类Graphic。所有几何图形都应该具备一个计算面积的方法。但是不同的几何图形计算面积的方式完全不同。
abstract class Graphic{
public abstract double getArea();
}
class Circle extends Graphic{
private double radius;
public Circle(double radius) {
super();
this.radius = radius;
}
public Circle() {
super();
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Graphic{
private double length;
private double width;
public Rectangle(double length, double width) {
super();
this.length = length;
this.width = width;
}
public Rectangle() {
super();
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double getArea() {
return length * width;
}
}
练习二:
1、声明抽象父类:Person,包含抽象方法: public abstract void walk(); public abstract void eat();
2、声明子类Man,继承Person 重写walk():大步流星走路 重写eat():狼吞虎咽吃饭 新增方法:public void smoke()实现为吞云吐雾
3、声明子类Woman,继承Person 重写walk():婀娜多姿走路 重写eat():细嚼慢咽吃饭 新增方法:public void buy()实现为买买买...
4、在测试类中创建子类对象,调用方法测试
public abstract class Person {
public abstract void walk();
public abstract void eat();
}
public class Man extends Person {
@Override
public void walk() {
System.out.println("大步流星走路");
}
@Override
public void eat() {
System.out.println("狼吞虎咽吃饭");
}
public void smoke(){
System.out.println("吞云吐雾");
}
}
public class Woman extends Person {
@Override
public void walk() {
System.out.println("婀娜多姿走路");
}
@Override
public void eat() {
System.out.println("细嚼慢咽吃饭");
}
public void buy(){
System.out.println("买买买...");
}
}
public class TestExer1 {
public static void main(String[] args) {
Man m = new Man();
m.eat();
m.walk();
m.smoke();
System.out.println("-------------------------");
Woman w = new Woman();
w.eat();
w.walk();
w.buy();
}
}
2.2 多态练习
练习一:
(1)声明抽象父类Traffic,包含抽象方法public abstract void drive()
(2)声明子类Car,Bicycle等,并重写drive方法
(3)在测试类的main中创建一个数组,有各种交通工具,遍历调用drive()方法 模拟马路上跑的各种交通工具
public abstract class Traffic {
public abstract void drive();
}
public class Car extends Traffic {
@Override
public void drive() {
System.out.println("滴滴滴...");
}
}
public class Bicycle extends Traffic {
@Override
public void drive() {
System.out.println("蹬蹬蹬。。。");
}
}
public class TestExer1 {
public static void main(String[] args) {
//右边这些是用匿名对象,初始化数组
Traffic[] arr = {new Car(),new Bicycle(),new Car(),new Bicycle()};
for (int i = 0; i < arr.length; i++) {
arr[i].drive();
}
}
}
练习二:
(1)声明一个抽象父类Person类,public abstract void toilet();
(2)声明一个子类Woman类,重写方法
(3)声明一个子类Man类,重写方法
(4)在测试类中声明一个方法,
public static void goToToilet(Person p){
p.toilet();
}
在main中,创建不同子类对象,调用goToToilet方法进行测试
public abstract class Person {
public abstract void toilet();
}
public class Man extends Person {
@Override
public void toilet() {
System.out.println("站着..");
}
}
public class Woman extends Person {
@Override
public void toilet() {
System.out.println("坐着..");
}
}
public class TestPerson {
public static void main(String[] args) {
goToToilet(new Woman());//隐含了Person p = new Woman();
goToToilet(new Man());//隐含了Person p = new Man();
}
public static void goToToilet(Person p){
p.toilet();
}
}
练习三:
1、声明一个父类Employee员工类型,有属性,姓名(String) 有方法,public abstract double earning() 用于返回实发工资 public String getInfo():显示姓名和实发工资
2、声明一个子类SalaryEmployee正式工,继承父类Employee,增加属性,薪资,工作日天数,请假天数 重写方法,public double earning()返回实发工资,实发工资 = 薪资 - 薪资/工作日天数 * 请假天数,
3、声明一个子类HourEmployee小时工,继承父类Employee 有属性,工作小时数,每小时多少钱 重写方法,public double earning()返回实发工资, 实发工资 = 每小时多少钱 * 小时数
4、声明一个子类Manager经理,继承SalaryEmployee,增加属性:奖金比例 重写方法,public double earning()返回实发工资,实发工资 = (薪资 - 薪资/工作日天数 * 请假天数)*(1+奖金比例)
5、你现在是财务,需要查看每个人的实发工资,并查看工资总额。 声明一个员工数组,存储各种员工,并遍历显示他们的姓名和实发工资,并计算工资总额
public abstract class Employee {
private String name;
public Employee(String name) {
super();
this.name = name;
}
public Employee() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract double earning();
public String getInfo() {
return "姓名:" + name + ",实发工资:" + earning();
}
}
public class SalaryEmployee extends Employee {
private double salary;
private int workingDays;//工作日天数,
private double offDays;//请假天数
public SalaryEmployee() {
super();
}
public SalaryEmployee(String name, double salary, int workingDays, double offDays) {
super(name);
this.salary = salary;
this.workingDays = workingDays;
this.offDays = offDays;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getWorkingDays() {
return workingDays;
}
public void setWorkingDays(int workingDays) {
this.workingDays = workingDays;
}
public double getOffDays() {
return offDays;
}
public void setOffDays(double offDays) {
this.offDays = offDays;
}
/*
* 重写方法,public double earning()返回实发工资,
实发工资 = 薪资 - 薪资/工作日天数 * 请假天数
*/
@Override
public double earning() {
return salary - salary/workingDays * offDays;
}
}
public class HourEmployee extends Employee {
private double moneyPerHour;
private double hours;
public HourEmployee() {
super();
}
public HourEmployee(String name, double moneyPerHour, double hours) {
super(name);
this.moneyPerHour = moneyPerHour;
this.hours = hours;
}
public double getMoneyPerHour() {
return moneyPerHour;
}
public void setMoneyPerHour(double moneyPerHour) {
this.moneyPerHour = moneyPerHour;
}
public double getHours() {
return hours;
}
public void setHours(double hours) {
this.hours = hours;
}
/*
* 重写方法,public double earning()返回实发工资,
实发工资 = 每小时多少钱 * 小时数
*/
@Override
public double earning() {
return moneyPerHour * hours;
}
}
public class Manager extends SalaryEmployee {
private double commisionPer;
public Manager() {
super();
}
public Manager(String name, double salary, int workingDays, double offDays, double commisionPer) {
super(name, salary, workingDays, offDays);
this.commisionPer = commisionPer;
}
public double getCommisionPer() {
return commisionPer;
}
public void setCommisionPer(double commisionPer) {
this.commisionPer = commisionPer;
}
@Override
public double earning() {
return super.earning() * (1+commisionPer);
}
}
public class TestEmployee {
public static void main(String[] args) {
Employee[] all = new Employee[3];
all[0] = new HourEmployee("张三", 50, 50);
all[1] = new SalaryEmployee("李四", 10000, 22, 1);
all[2] = new Manager("老王", 20000, 22, 0, 0.3);
double sum = 0;
for (int i = 0; i < all.length; i++) {
System.out.println(all[i].getInfo());
sum += all[i].earning();
}
System.out.println("总额:" + sum);
}
}
2.3 父子类之间类型转换练习
练习一:
1、声明一个父类Employee员工类型, 有属性,姓名(String),出生日期(MyDate类型,也是自定义的含年,月,日属性日期类型) 有方法,public abstract double earning() public String getInfo():显示姓名和实发工资
2、声明一个子类SalaryEmployee正式工,继承父类Employee 增加属性,薪资,工作日天数,请假天数 重写方法,public double earning()返回实发工资, 实发工资 = 薪资 - 薪资/工作日天数 * 请假天数, 重写方法,public String getInfo():显示姓名和实发工资,月薪,工作日天数,请假天数
3、声明一个子类HourEmployee小时工,继承父类Employee 有属性,工作小时数,每小时多少钱 重写方法,public double earning()返回实发工资, 实发工资 = 每小时多少钱 * 小时数 重写方法,public String getInfo():显示姓名和实发工资,时薪,工作小时数 增加方法,public void leave():打印查看使用工具是否损坏,需要赔偿
4、声明一个子类Manager经理,继承SalaryEmployee 增加属性:奖金,奖金比例 重写方法,public double earning()返回实发工资, 实发工资 = (薪资 - 薪资/工作日天数 * 请假天数)*(1+奖金比例) 重写方法,public String getInfo():显示姓名和实发工资,月薪,工作日天数,请假天数,奖金比例
5、声明一个员工数组,存储各种员工, 你现在是人事,从键盘输入当前的月份,需要查看每个人的详细信息。 如果他是正式工(包括SalaryEmployee和Manager),并且是本月生日的,祝福生日快乐,通知领取生日礼物。如果是HourEmployee显示小时工,就进行完工检查,即调用leave方法
public abstract class Employee {
private String name;
private MyDate birthday;
public Employee(String name, MyDate birthday) {
super();
this.name = name;
this.birthday = birthday;
}
public Employee(String name, int year, int month, int day) {
super();
this.name = name;
this.birthday = new MyDate(year, month, day);
}
public Employee() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
public abstract double earning();
public String getInfo(){
return "姓名:" + name + ",生日:" + birthday.getInfo() +",实发工资:" + earning();
}
}
public class SalaryEmployee extends Employee {
private double salary;
private int workingDays;//工作日天数,
private double offDays;//请假天数
public SalaryEmployee() {
super();
}
public SalaryEmployee(String name, int year, int month, int day, double salary, int workingDays, double offDays) {
super(name, year, month, day);
this.salary = salary;
this.workingDays = workingDays;
this.offDays = offDays;
}
public SalaryEmployee(String name, MyDate birthday, double salary, int workingDays, double offDays) {
super(name, birthday);
this.salary = salary;
this.workingDays = workingDays;
this.offDays = offDays;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getWorkingDays() {
return workingDays;
}
public void setWorkingDays(int workingDays) {
this.workingDays = workingDays;
}
public double getOffDays() {
return offDays;
}
public void setOffDays(double offDays) {
this.offDays = offDays;
}
/*
* 重写方法,public double earning()返回实发工资,
实发工资 = 薪资 - 薪资/工作日天数 * 请假天数
*/
@Override
public double earning() {
return salary - salary/workingDays * offDays;
}
@Override
public String getInfo() {
return super.getInfo() + ",月薪:" + salary + ",工作日:" + workingDays +",请假天数:" + offDays;
}
}
public class HourEmployee extends Employee {
private double moneyPerHour;
private double hours;
public HourEmployee() {
super();
}
public HourEmployee(String name, int year, int month, int day, double moneyPerHour, double hours) {
super(name, year, month, day);
this.moneyPerHour = moneyPerHour;
this.hours = hours;
}
public HourEmployee(String name, MyDate birthday, double moneyPerHour, double hours) {
super(name, birthday);
this.moneyPerHour = moneyPerHour;
this.hours = hours;
}
public double getMoneyPerHour() {
return moneyPerHour;
}
public void setMoneyPerHour(double moneyPerHour) {
this.moneyPerHour = moneyPerHour;
}
public double getHours() {
return hours;
}
public void setHours(double hours) {
this.hours = hours;
}
/*
* 重写方法,public double earning()返回实发工资,
实发工资 = 每小时多少钱 * 小时数
*/
@Override
public double earning() {
return moneyPerHour * hours;
}
@Override
public String getInfo() {
return super.getInfo() + ",时薪:" + moneyPerHour + ",小时数:" + hours;
}
public void leave(){
System.out.println("小时工,查看使用工具是否损坏,需要赔偿,然后拿钱走人");
}
}
public class Manager extends SalaryEmployee {
private double commisionPer;
public Manager() {
super();
}
public Manager(String name, int year, int month, int day, double salary, int workingDays, double offDays,
double commisionPer) {
super(name, year, month, day, salary, workingDays, offDays);
this.commisionPer = commisionPer;
}
public Manager(String name, MyDate birthday, double salary, int workingDays, double offDays, double commisionPer) {
super(name, birthday, salary, workingDays, offDays);
this.commisionPer = commisionPer;
}
public double getCommisionPer() {
return commisionPer;
}
public void setCommisionPer(double commisionPer) {
this.commisionPer = commisionPer;
}
@Override
public double earning() {
return super.earning() * (1+commisionPer);
}
@Override
public String getInfo() {
return super.getInfo() + ",奖金比例:" + commisionPer;
}
}
public class TestEmployee {
public static void main(String[] args) {
Employee[] all = new Employee[3];
/*all[0] = new HourEmployee("张三", new MyDate(1990, 5, 1), 50, 50);
all[1] = new SalaryEmployee("李四", new MyDate(1991, 1, 1), 10000, 22, 1);
all[2] = new Manager("老王", new MyDate(1987, 12, 8), 20000, 22, 0, 0.3);*/
all[0] = new HourEmployee("张三", 1990, 5, 1, 50, 50);
all[1] = new SalaryEmployee("李四", 1991, 1, 1, 10000, 22, 1);
all[2] = new Manager("老王", 1987, 12, 8, 20000, 22, 0, 0.3);
//从键盘输入当前的月份
Scanner input = new Scanner(System.in);
System.out.print("请输入当前月份:");
int month;
while(true){
month = input.nextInt();
if(month>=1 && month<=12){
break;
}
}
input.close();
for (int i = 0; i < all.length; i++) {
System.out.println(all[i].getInfo());
if(all[i] instanceof SalaryEmployee){
if(month == all[i].getBirthday().getMonth()){
System.out.println(all[i].getName() +"生日快乐,领取生日补助购物卡");
}
}else{
HourEmployee he = (HourEmployee) all[i];
he.leave();
}
}
}
}