最简单的回调机制如下:
public class CallbackDemo {
public static void main(String[] args) {
new A().aa();
}
}
class A{
public void aa(){
new B().b();
System.out.println("This is aa!");
}
public void ab(){
System.out.println("This is ab!");
}
}
class B{
public void b(){
new A().ab();
System.out.println("This is b!");
}
}
执行的结果如下:
This is ab!
This is b!
This is aa!
上面的例子看上去没有什么实际的应用,现在我们想象这样的一个场景:每个人参加工作之后都会面临交税的事,但是除了税务财务人员,其他人并不关心具体的算法,他们只关心交了多少税(2019年的税法复杂了点,采用);
1.应纳税所得额 = 税前工资收入金额 - 五险一金(个人缴纳部分) -费用减除额
2.应纳税额 = 应纳税所得额 x 税率 - 速算扣除数
级数 | 全年应纳税所得额 | 税率(%) | 速算扣除数 |
---|---|---|---|
1 | 不超过36000元的 | 3 | 0 |
2 | 超过36000元至144000元的部分 | 10 | 2520 |
3 | 超过144000元至300000元的部分 | 20 | 16920 |
4 | 超过300000元至420000元的部分 | 25 | 31920 |
5 | 超过420000元至660000元的部分 | 30 | 52920 |
6 | 超过660000元至960000元的部分 | 35 | 85920 |
7 | 超过960000元的部分 | 45 | 181920 |
最原始的代码:
public class CallbackDemo2 {
public static void main(String[] args) {
Student xiaomiStudent = new Student("小米", 200000, 6000, 5000);
xiaomiStudent.say();
}
}
class Student{
private String name;
private int wages;
private int five;
private int jian;
Student(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 应纳税所得额 = 税前工资收入金额 - 五险一金(个人缴纳部分) -费用减除额
// 应纳税额 = 应纳税所得额 x 税率 - 速算扣除数
public int getTax(int wages,int five,int jian){
int cost;
int level = wages<36000?1:wages<144000?2:wages<300000?3:wages<420000?4:wages<660000?5:wages<960000?6:7;
switch(level){
case 1:
cost= (wages-five-jian)*3/100;
break;
case 2:
cost= (wages-five-jian)*10/100-2520;
break;
case 3:
cost= (wages-five-jian)*20/100-16920;
break;
case 4:
cost= (wages-five-jian)*25/100-31920;
break;
case 5:
cost= (wages-five-jian)*30/100-52920;
break;
case 6:
cost= (wages-five-jian)*35/100-85920;
break;
case 7:
cost= (wages-five-jian)*45/100-181920;
break;
default:
cost = 0;
}
return cost;
}
public void say() {
System.out.println(this.name + ":需要交税:" + getTax(this.wages,this.five,this.jian));
}
}
运行结果:
小米:需要交税:20880
现在有一个老师需要完成交税的任务,将上面的类在写一遍?如果又有销售需要交税。。。现在我们将公共的方法提取出来。
public class CallbackDemo2 {
public static void main(String[] args) {
Student xiaomiStudent = new Student("小米同学", 200000, 6000, 5000);
xiaomiStudent.say();
Tercher laoshiTercher = new Tercher("大米老师", 400000, 8000, 8000);
laoshiTercher.say();
}
}
class Student{
private String name;
private int wages;
private int five;
private int jian;
Student(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println(this.name + ":需要交税:" + new Common().getTax(this.wages,this.five,this.jian));
}
}
class Common{
// 应纳税所得额 = 税前工资收入金额 - 五险一金(个人缴纳部分) -费用减除额
// 应纳税额 = 应纳税所得额 x 税率 - 速算扣除数
public int getTax(int wages,int five,int jian){
int cost;
int level = wages<36000?1:wages<144000?2:wages<300000?3:wages<420000?4:wages<660000?5:wages<960000?6:7;
switch(level){
case 1:
cost= (wages-five-jian)*3/100;
break;
case 2:
cost= (wages-five-jian)*10/100-2520;
break;
case 3:
cost= (wages-five-jian)*20/100-16920;
break;
case 4:
cost= (wages-five-jian)*25/100-31920;
break;
case 5:
cost= (wages-five-jian)*30/100-52920;
break;
case 6:
cost= (wages-five-jian)*35/100-85920;
break;
case 7:
cost= (wages-five-jian)*45/100-181920;
break;
default:
cost = 0;
}
return cost;
}
}
class Tercher{
private String name;
private int wages;
private int five;
private int jian;
Tercher(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println(this.name + ":需要交税:" + new Common().getTax(this.wages,this.five,this.jian));
}
}
运行结果:
小米同学:需要交税:20880
大米老师:需要交税:64080
这里我们调用了一个公共类替我们完成了税的计算,但是与回调显然是有区别的。想想这样的一个场景,现在公司要求统计每个人全年的交税金额,财务方面更希望是能得到银行给的数据,也就是说员工查询后,公共类将结果也返回了财务部门;使用回调功能需要将自身的一部分方法暴露出来;
public class CallbackDemo2 {
public static void main(String[] args) {
Student xiaomiStudent = new Student("小米同学", 200000, 6000, 5000);
xiaomiStudent.say();
Tercher laoshiTercher = new Tercher("大米老师", 400000, 8000, 8000);
laoshiTercher.say();
}
}
class Student implements People{
private String name;
private int wages;
private int five;
private int jian;
Student(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
public int getTax(int wages, int five, int jian) {
System.out.println(name + "询问银行交的税");
return new Common().getTax(wages, five, jian);
}
public void say() {
new Bank().say(wages, five, jian,name,this);
}
}
interface People{
public int getTax(int wages,int five,int jian);
}
class Bank{
public void say(int wages, int five, int jian,String name, People people){
System.out.println("银行说:"+name+"交税:"+ people.getTax(wages, five, jian));
}
}
class Common{
// 应纳税所得额 = 税前工资收入金额 - 五险一金(个人缴纳部分) -费用减除额
// 应纳税额 = 应纳税所得额 x 税率 - 速算扣除数
public int getTax(int wages,int five,int jian){
int cost;
int level = wages<36000?1:wages<144000?2:wages<300000?3:wages<420000?4:wages<660000?5:wages<960000?6:7;
switch(level){
case 1:
cost= (wages-five-jian)*3/100;
break;
case 2:
cost= (wages-five-jian)*10/100-2520;
break;
case 3:
cost= (wages-five-jian)*20/100-16920;
break;
case 4:
cost= (wages-five-jian)*25/100-31920;
break;
case 5:
cost= (wages-five-jian)*30/100-52920;
break;
case 6:
cost= (wages-five-jian)*35/100-85920;
break;
case 7:
cost= (wages-five-jian)*45/100-181920;
break;
default:
cost = 0;
}
return cost;
}
}
class Tercher implements People{
private String name;
private int wages;
private int five;
private int jian;
Tercher(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
public int getTax(int wages, int five, int jian) {
System.out.println(name + "询问银行交的税");
return new Common().getTax(wages, five, jian);
}
public void say() {
new Bank().say(wages, five, jian,name,this);
}
}
运行结果:
小米同学询问银行交的税
银行说:小米同学交税:20880
大米老师询问银行交的税
银行说:大米老师交税:64080
这里的方法:
public int getTax(int wages, int five, int jian) {
System.out.println(name + "询问银行交的税");
return new Common().getTax(wages, five, jian);
}
就是一个回调方法,显然代码看上去有点傻傻的,因为看上去多此一举,为什么要借助Bank类,这是因为我们这里使用的是同步回调,面对一些复杂的业务我们想得到这样的结果:
小米同学询问银行交的税
大米老师询问银行交的税
银行说:小米同学交税:20880
银行说:大米老师交税:64080
public class CallbackDemo2 {
public static void main(String[] args) {
Student xiaomiStudent = new Student("小米同学", 200000, 6000, 5000);
Tercher laoshiTercher = new Tercher("大米老师", 400000, 8000, 8000);
new Thread(xiaomiStudent).start();
new Thread(laoshiTercher).start();
}
}
class Student implements People,Runnable {
private String name;
private int wages;
private int five;
private int jian;
Student(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
public int getTax(int wages, int five, int jian) {
System.out.println(name + "询问银行交的税");
return new Common().getTax(wages, five, jian);
}
public void say() {
new Bank().say(wages, five, jian,name,this);
}
@Override
public void run() {
say();
}
}
interface People{
public int getTax(int wages,int five,int jian);
}
class Bank{
public void say(int wages, int five, int jian,String name, People people){
int shui = people.getTax(wages, five, jian);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("银行说:"+name+"交税:"+ shui);
}
}
class Common{
// 应纳税所得额 = 税前工资收入金额 - 五险一金(个人缴纳部分) -费用减除额
// 应纳税额 = 应纳税所得额 x 税率 - 速算扣除数
public int getTax(int wages,int five,int jian){
int cost;
int level = wages<36000?1:wages<144000?2:wages<300000?3:wages<420000?4:wages<660000?5:wages<960000?6:7;
switch(level){
case 1:
cost= (wages-five-jian)*3/100;
break;
case 2:
cost= (wages-five-jian)*10/100-2520;
break;
case 3:
cost= (wages-five-jian)*20/100-16920;
break;
case 4:
cost= (wages-five-jian)*25/100-31920;
break;
case 5:
cost= (wages-five-jian)*30/100-52920;
break;
case 6:
cost= (wages-five-jian)*35/100-85920;
break;
case 7:
cost= (wages-five-jian)*45/100-181920;
break;
default:
cost = 0;
}
return cost;
}
}
class Tercher implements People,Runnable{
private String name;
private int wages;
private int five;
private int jian;
Tercher(String name,int wages,int five,int jian){
this.name = name;
this.wages = wages;
this.five = five;
this.jian = jian;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public int getFive() {
return five;
}
public void setFive(int five) {
this.five = five;
}
public int getJian() {
return jian;
}
public void setJian(int jian) {
this.jian = jian;
}
public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
public int getTax(int wages, int five, int jian) {
System.out.println(name + "询问银行交的税");
return new Common().getTax(wages, five, jian);
}
public void say() {
new Bank().say(wages, five, jian,name,this);
}
@Override
public void run() {
say();
}
}
执行结果:
小米同学询问银行交的税
大米老师询问银行交的税
银行说:大米老师交税:64080
银行说:小米同学交税:20880
这里采用了多线程,实际上本质是采用了阻塞,异步阻塞。小米同学在询问银行后,她的线程是在阻塞中的,直到银行处理完成后,她的线程才继续执行。关于异步与同步,阻塞与非阻塞的内容 会在另外的博文介绍。