【问题标题】:Two versions of the same Java class where each has a different superclass同一个 Java 类的两个版本,每个版本都有不同的超类
【发布时间】:2023-04-04 07:25:02
【问题描述】:

在 Java 中编写同一类的两个版本且每个版本都有不同的超类的最简洁方法是什么?最干净的意思是 DRY(重复最少的代码)。这两个类将具有相似但不同的名称和相同的代码。

应用程序是 Android:MyActivity 类扩展了 ActionBarActivity。 MyActivity34 类(用于 API 级别 3/4)扩展了 Activity,但具有与 MyActivity 相同的代码。我不想保留所有内容的两个副本(在 C++ 中,我会为此使用预处理器)。更改超类不是一种选择。

谢谢。

注意:ActionBarActivity 类不能用于 API 级别 3 或 4(运行时错误),因此 MyActivity34 不能在继承路径中的任何位置使用它。

【问题讨论】:

  • 如果它们都包含相同的代码,请将所有代码移至第三个类,并让前两个类委托到第三个类。
  • ActionBarActivity 扩展 Activity。你为什么不创建一个抽象类,在两个类中你需要的所有代码都相同,然后你创建两个扩展那个超类的类?
  • 如果我正确理解你的想法,抽象类将不得不扩展超类之一,ActionBarActivity,而不是 Activity。 ActionBarActivity 类不能用于 API 级别 3 或 4(运行时错误)。

标签: java android oop dry


【解决方案1】:

我可能会说你最好的选择是使用组合来封装任何重复的代码。创建一个包含所有共享代码的类,并从 MyActivity 和 MyActivity34 类中调用它。组合通常比奇怪的继承结构更好/更干净。

【讨论】:

    【解决方案2】:

    使用所有方法创建一个接口,例如MyCommonActivityInterface

    public interface MyCommonActivityInterface {
        public void sayHello();
        public void sayGoodbye();
    }
    

    使用所有代码创建一个通用活动

    public class MyCommonActivity implements MyCommonActivityInterface {
        ...
        public void sayHello() {Log.d("MyCommonActivity", "says hello")};
        public void sayGoodbye() {Log.d("MyCommonActivity", "says goodbye")};
        ...
    }
    

    现在您可以在两个活动中重用公共代码

    public class MyActivity34 extends Activity {
        MyCommonActivityInterface common = new MyCommonActivity();
        public void sayHello() {common.sayHello()};
        public void sayGoodbye() {common.sayGoodbye()};
    }
    
    public class MyActivity extends ActionBarActivity {
        MyCommonActivityInterface common = new MyCommonActivity();
        public void sayHello() {common.sayHello()};
        public void sayGoodbye() {common.sayGoodbye()};
    }
    

    其实这个接口可以省略,但如果你需要在替代品或类似物之间进行交换,它会派上用场。

    依赖注入的强大功能给我留下了深刻的印象,它可以让这类事情变得更加简洁。

    有一个名为Dagger 的库添加了对android 的DI 支持。它的学习曲线有些陡峭,但对我来说这一切都是值得的。

    在此示例中,您将能够执行以下操作:

    @Singleton
    public class MyCommonActivity  {
    
        // Example with context to show that it will be automagically injected
    
        @Inject
        public MyCommonActivity(@ForActivity Context context) {}
        ...
        public void sayHello() {Log.d("MyCommonActivity", "says hello")};
        public void sayGoodbye() {Log.d("MyCommonActivity", "says goodbye")};
        ...
    }
    
    public class MyActivity34 extends Activity {
    
        @Inject MyCommonActivity common;
    
        public void sayHello() {common.sayHello()};
        public void sayGoodbye() {common.sayGoodbye()};
    }
    
    public class MyActivity extends ActionBarActivity {
    
        @Inject MyCommonActivity common;
    
        public void sayHello() {common.sayHello()};
        public void sayGoodbye() {common.sayGoodbye()};
    }
    

    有很多独立的代码类,其中一些依赖于其他类,或者需要一个 Context 对象等,.. 只需在您需要的时间和地点添加 @Inject 行就可以节省很多代码行!

    当我们添加它时,看看ButterKnife,它更简单,但也只适用于注入视图。仍然非常强大和整洁。

    【讨论】:

      猜你喜欢
      • 2013-04-02
      • 2019-10-12
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多