2

假设你有一个类extends Activityand implements MyInterface, where Activitycontains public final void setProgress(int progress)and MyInterfacecontainspublic abstract void setProgress(int progress)

我需要从接口覆盖该方法,但我不能因为Activty说它是最终的并且不能被覆盖。

我该怎么办?

例子:

public class MyActivity extends Activity implements MyInterface
{
  @Override
  protected void onCreate(Bundle bundle)
  {
    //stuff goes here
  }
  //Cannot override the final method from Activity
  @Override
  public void setProgress(int progress)
  {
  }

}

让我们也扩展这个问题并说您无法访问MyInterface更改它的来源,在这种情况下该怎么办?

4

5 回答 5

3

使用装饰器设计模式。

这是装饰器模式的简化示例。(改编自互联网和 polygenelubricants 对 SO 的回答)

注意:在我们开始从接口中删除 abstract 关键字之前,这是错误的语法

类层次结构被重组为static内部类,以便整个示例包含在一个编译单元中(如 ideone.com 上所示):

这是预期类层次结构的图表概述

类层次结构概述

public class AnimalDecorator {

    static interface Animal {
        public String makeNoise();
            public void wagTail();
            //other methods
    }   
    static class Dog implements Animal {
        public final String makeNoise() { return "woof"; }
        public final void wagTail() { //do wag tail action }
    }
    static class DogDecorator implements Animal {
            //delegate
            private Animal animal;

            public DogDecorator (Animal animal){this.animal = animal;}
        public String makeNoise() { animal.makeNoise();}
            public void wagTail() { animal.wagTail();}

    }

    static class LoudDog extends DogDecorator {
        @Override public String makeNoise() {
            return "WOOF WOOF WOOF!!!";
        }
    }
}

所以这里我们有一个简单的Animal层次结构,带有Dog子类。我们还有一个DogDecorator装饰器——也是一个Animal——简单地将所有方法委托给另一个Animal。也就是说,它并没有真正做任何有效的装饰,但它已经准备好被子类化,以便可以添加实际的装饰。

我们这里只有两种方法,makeNoise()wagTail()。然后我们创建我们想要的类LoudDog并使用它。(考虑Animal有很多方法的情况;那么Normal将是最有价值的)。

请注意,我们甚至可以将一种装饰堆叠在另一种之上。确切的实现细节可能会有所不同,但这个简化的示例几乎抓住了装饰器模式的精髓。


脚步

  1. 将原始“组件”类子类化为“装饰器”类(参见 UML 图);
  2. 在 Decorator 类中,添加一个 Component 指针作为字段;
  3. 传递一个 Component 给 Decorator 构造函数来初始化 Component 指针;
  4. 在装饰器类中,将所有“组件”方法重定向到“组件”指针;和
  5. 在 ConcreteDecorator 类中,覆盖任何需要修改其行为的组件方法。

也可以看看

  • Effective Java 第 2 版,第 18 条:首选接口胜于抽象类

相关问题

于 2013-05-10T16:29:57.637 回答
0

编辑:

在这种情况下,该类不能覆盖 final 方法。因此,要么您的接口将具有与父类完全相同的签名(因此接口是通过继承自动实现的),或者您创建一个具有不同名称的方法。

解决方案在很大程度上取决于具体情况,这里没有教科书的解决方案。

于 2013-05-10T15:50:21.797 回答
0

您不能覆盖 final 方法,因为在 Java 编程语言中,final 关键字用于定义以后无法更改的实体。

形成Java 语言规范

于 2013-05-10T15:55:18.103 回答
0

没试过,但可以试一试。您也必须在子类中实现 MyInterface,并且可以覆盖 MyInterface 而不是其超类的 setProgress 方法。

应该说..一个好问题:)

于 2013-05-10T15:55:42.750 回答
0

没有你的MyActivity实现MyInterface,而是创建实现它的匿名或内部类。

这样,您仍然可以访问MyActivity与.setProgress(int)final Activity.setProgress(int)

于 2013-05-10T16:10:26.570 回答