如何在仅允许继承DecrementCarousel的HalvingCarousel子类中重写CarouselRun类的方法?
解决方案:通过重写
run方法返回自定义的CarouselRun子类 要实现HalvingCarousel中重写CarouselRun的方法,核心思路是利用多态:在子类中重写父类的run方法,返回一个继承自CarouselRun的自定义子类实例,在这个子类里重写next方法来实现减半逻辑。
第一步:修复父类的设计缺陷(可选但推荐)
原DecrementingCarousel中使用了static的arr和capacity,这会导致所有实例共享同一个数组,多个HalvingCarousel实例会互相干扰。我们先把这些改为实例变量,并将CarouselRun改为内部类(这样它能访问外部类的实例变量):
public class DecrementingCarousel { private int[] arr; private int capacity; private int counter = 0; private boolean alreadyExecuted = false; private boolean alreadyRun = false; public DecrementingCarousel(int capacity) { this.capacity = capacity; this.arr = new int[capacity]; } public boolean addElement(int element) { if (alreadyExecuted) return false; if (counter < capacity && element > 0) { arr[counter] = element; counter++; return true; } return false; } public CarouselRun run() { alreadyExecuted = true; if (alreadyRun) return null; alreadyRun = true; return new CarouselRun(); } // 将CarouselRun改为内部类,并用protected修饰position让子类访问 public class CarouselRun { protected int position = 0; public int next() { int count = 0; while (count < arr.length && arr[position %= arr.length] <= 0) { position++; count++; } if (count == arr.length) return -1; return arr[position++]--; } public boolean isFinished() { for (int var : arr) { if (var > 0) return false; } return true; } } }
第二步:实现HalvingCarousel子类
在HalvingCarousel中重写run方法,返回自定义的HalvingCarouselRun实例,并重写next方法实现减半逻辑:
public class HalvingCarousel extends DecrementingCarousel { public HalvingCarousel(int capacity) { super(capacity); } @Override public CarouselRun run() { // 复制父类run方法的状态控制逻辑,确保只有第一次调用有效 alreadyExecuted = true; if (alreadyRun) return null; alreadyRun = true; return new HalvingCarouselRun(); } // 自定义CarouselRun子类,重写next方法 private class HalvingCarouselRun extends CarouselRun { @Override public int next() { int count = 0; // 找到第一个大于0的元素,逻辑和父类一致 while (count < arr.length && arr[position %= arr.length] <= 0) { position++; count++; } if (count == arr.length) return -1; // 实现减半逻辑:返回当前值,然后将元素除以2(整数除法自动向下取整) int currentValue = arr[position]; arr[position] = currentValue / 2; position++; return currentValue; } // isFinished方法可以直接复用父类的,因为逻辑都是检查所有元素是否<=0 } }
逻辑验证示例
假设我们使用HalvingCarousel的流程:
HalvingCarousel carousel = new HalvingCarousel(1); carousel.addElement(8); CarouselRun run = carousel.run(); System.out.println(run.next()); // 输出8,数组元素变为4 System.out.println(run.next()); // 输出4,数组元素变为2 System.out.println(run.next()); // 输出2,数组元素变为1 System.out.println(run.next()); // 输出1,数组元素变为0 System.out.println(run.next()); // 输出-1,所有元素已耗尽 System.out.println(run.isFinished()); // 输出true
关键说明
- 多态的运用:父类
run返回CarouselRun,子类返回其子类HalvingCarouselRun,符合里氏替换原则,调用者无需关心具体类型,就能使用重写后的方法。 - 状态控制一致性:重写
run方法时,必须复制父类的alreadyExecuted和alreadyRun逻辑,确保只有第一次调用run能返回有效对象,后续调用返回null。 - 内部类的访问权限:将
CarouselRun的position改为protected,让子类HalvingCarouselRun可以直接访问该变量,避免重复定义。
内容的提问来源于stack exchange,提问作者MusicVoice
相关产品推荐
相关产品推荐

