
水果店中有各种水果的库存积累,需要大甩卖,可以利用java的多态实现

现在有水果接口Fruit,访问者Visit
public class Visit {
//苹果计价
public int sell(Apple apple){
System.out.println("apple's price: ¥50");
return 50;
}
//桔子计价
public int sell(Orange orange){
System.out.println("orange's price: ¥20");
return 20;
}
//香蕉计价
public int sell(Banana banana){
System.out.println("banana's price: ¥30");
return 30;
}
//其它水果计价
public int sell(Fruit fruit){
System.out.println("other price: ¥10");
return 10;
}
}
public class VisitClient {
private static Visit visit = new Visit();
private static List<Fruit> list = new ArrayList<>();//库存
static {
list.add(StaticFactory.getFruitApple());
list.add(StaticFactory.getFruitOrange());
list.add(StaticFactory.getFruitBanana());
list.add(StaticFactory.getFruitApple());
list.add(StaticFactory.getFruitOrange());
}
//统计库存
private static int price() {
int total = 0;
for (Fruit fruit : list) {
total += visit.sell(fruit);
// total += fruit.accept(visit);
}
System.out.println("总价值:" + total);
return total;
}
public static void main(String[] args) {
price();
}
}
虽然visit的sell方法是多态的,但是由于java的多态方法重载是静态的,无法动态识别真实对象的类型,所以在for循环中,sell的方法的参数都被认为是Fruit类型,结果都调用了sell(Fruit fruit)方法了
那么如何优雅地实现动态重载呢
虽然多态参数无法动态识别真实对象,但是如果在真实对象的内部使用this指针可以正确识别真实对象类型
public class Apple implements Fruit {
private int price = 100;
public Apple(){
}
public Apple(int price){
this.price = price;
}
@Override
public int price() {
return price;
}
@Override
public void draw() {
System.out.print("苹果红富士");
}
public int accept(Visit visit){
return visit.sell(this);//指针可以传递真实类型
}
public static void main(String[] args) {
Visit visit = new Visit();
new Apple().accept(visit);
}
}
public interface Fruit {
int price();
void draw();
int accept(Visit visit);
}
访问者模式


本来是通过Visit的多态方法直接实现功能,现在为了动态重载参数类型,使用this关键字在真实对象内部识别真实对象类型
public class VisitClient {
private static Visit visit = new Visit();
private static List<Fruit> list = new ArrayList<>();//库存
static {
list.add(StaticFactory.getFruitApple());
list.add(StaticFactory.getFruitOrange());
list.add(StaticFactory.getFruitBanana());
list.add(StaticFactory.getFruitApple());
list.add(StaticFactory.getFruitOrange());
}
//统计库存
private static int price() {
int total = 0;
for (Fruit fruit : list) {
//total += visit.sell(fruit);
total += fruit.accept(visit);//在真实内部调用visit功能识别真实对象类型
}
System.out.println("总价值:" + total);
return total;
}
public static void main(String[] args) {
price();
}
}
总结
- 访问者模式是利用双重分派机制来弥补java多态中方法重载是静态化的不足,实现优雅变成的目的
网友评论