【问题标题】:what scenario should abstract class used in java?java中抽象类应该使用什么场景?
【发布时间】:2015-05-06 14:19:46
【问题描述】:

我对OOPS概念不熟悉,我在使用抽象类时有疑问,请解决我的疑问。

我有四个类,例如:A 类、B 类、C 类和主类。

A、B、C类包含相同的方法名但方法定义不同

实现是这样的,

    class A                          
    {
       getValue();
       setValue();
    }

    class B                          
    {
       getValue();
       setValue();
}

    class C                          
    {
       getValue();
       setValue();
    }

在Main类中,我需要调用setValue()或者getValue(),可以是上面三个类中的任何一个,这个场景如何实现?

    class Main
    {
      Main()
    {}
        x.setValue();
        x.getValue();
    }

其中 x 可以是 A 类或 B 类或 C 类的对象。

【问题讨论】:

    标签: java class oop interface abstract-class


    【解决方案1】:

    抽象类定义了可用的方法。在你的情况下,这将是

    abstract class YourAbstractClass {
         abstract public int getValue();
         abstract public void setValue(int i);
    }
    

    现在你的 A、B 和 C 类可以继承这个类了。

    class A extends YourAbstractClass {
         public int getValue() { return 23; }
         public void setValue(int i) { /* set i */ }
    }
    class B extends YourAbstractClass {
         public int getValue() { return -3; }
         public void setValue(int i) { /* set i */ }
    }
    class C extends YourAbstractClass {
         public int getValue() { return 3; }
         public void setValue(int i) { /* set i */ }
    }
    

    在你的主类中,你可以像这样使用它:

    public class Execution {
        public static void main(String[] args) {
            YourAbstractClass o = new A();
            o.getValue();
            o.setValue(3);
        }
    }
    

    【讨论】:

      【解决方案2】:

      在您的特定情况下,您不需要抽象类而是接口:

      public interface I {
         Object getValue();
         Object setValue();
      }
      

      那么你的 3 个类 A、B 和 C 必须实现这个接口:

      class A implements I {
         Object getValue() {...}
         void setValue( someParam) {...}
      }
      
          class B implements I {
         Object getValue() {...}
         void setValue( someParam) {...}
      }
      
      class C implements I {
         Object getValue() {...}
         void setValue( someParam) {...}
      }
      

      最后在你的主课上:

      class Main
      {
        Main()
      {
          I x = callWhateverYouWantReturningABOrC();
          x.setValue();
          x.getValue();
      }
      

      【讨论】:

        【解决方案3】:

        您可以通过以下几种方式实现:

        public interface Valuable {
            void getValue();
            void setValue();
        }
        
        class A  implements Valuable {
           getValue() { ... }
           setValue() { ... }
        }
        
        class B  implements Valuable {
           getValue() { ... }
           setValue() { ... }
        }
        
        class C  implements Valuable {
           getValue() { ... }
           setValue() { ... }
        }
        

        或者……

        abstract class Valuable {
            void getValue() { ... }
            void setValue() { ... }
        }
        
        class A extends Valuable {
        }
        
        class B extends Valuable {
        }
        
        class C extends Valuable {
        }
        

        或者...一个混合的接口和抽象类。

        哪个更合适取决于很多事情,包括方法实现是否相同。如果是,那么abstract 类会消除一些重复代码。

        【讨论】:

          【解决方案4】:

          如果我的问题没问题,你想创建一个界面:

          interface I {
            int getValue();
            void setValue(int x);
          }
          

          你的类将实现它:

          class A implements I {..};
          class B implements I {..};
          class C implements I {..};
          

          然后在您的 Main 类中,您可以拥有方法,该方法不必知道 x 变量是哪个具体实现(ABC),它可以调用它方法:

          {
            I x = new A(); // or new B() or C()
            x.setValue(1);
            x.getValue();
          }
          

          【讨论】:

          • 我可以通过使用抽象类本身来做这个操作,那我为什么要选择接口呢?
          • 在Java中,你可以只继承一个类,但可以继承多个接口。所以通常你应该为类使用接口,你不需要默认方法实现(尽管在 Java 8 中,在接口中也是可能的)。因此,当您只想定义通用调用签名时,请使用接口。例如。接口Persistable 与方法load()save()。如果您有一些实现并且您只是指定一些细节(即实现抽象方法),请使用抽象类。例如。摆动库中的 AbstractListModel。
          • 类 Main { Main() { I x = callWhateverYouWantReturningABOrC(); x.setValue(); x.getValue();我有一个 api Z() 它返回这三个类中的任何一个,例如: x Z();在这种情况下,我将如何将 x 转换为相应的 Class (A or B or C) ?,我需要像 ((A/B/C)x) Z();
          • 关键是你从不强制转换为具体类(ABC),你只使用类型I 而不在乎它是哪个类。接口I 包含其后代的共同特征(方法),您必须只使用它们。所以让z()返回I:public I z() { }
          【解决方案5】:

          您可以使 Main 成为一个接口。 接口是一个纯抽象类。

          public interface Main {
             void setValue();
             void getValue();
          }
          

          然后制作A、B、C类实现Main接口

          public class A implements Main {
             @Override
             public void setValue() {
                ...
             }
          
             @Override
             public void getValue() {
                ...
             }
          }
          
          public class B implements Main {
             @Override
             public void setValue() {
                ...
             }
          
             @Override
             public void getValue() {
                ...
             }
          }
          
          
          public class C implements Main {
             @Override
             public void setValue() {
                ...
             }
          
             @Override
             public void getValue() {
                ...
             }
          }
          

          【讨论】:

          • 谢谢大家,我从你们那里得到了解决方案。。还有一个疑问,我应该在什么情况下使用接口,如果我没有错,这种情况是对的,所有方法都应该使用的情况实施?
          猜你喜欢
          • 1970-01-01
          • 2011-06-09
          • 1970-01-01
          • 2016-06-23
          • 2022-01-02
          • 2011-09-24
          • 2018-06-26
          • 2015-03-13
          • 2012-02-12
          相关资源
          最近更新 更多