【问题标题】:Abstract class with all methods abstract - Practical Example具有所有方法的抽象类抽象 - 实际示例
【发布时间】:2013-06-18 02:43:40
【问题描述】:

我问的是一个非常基本的问题,它可能被标记为重复(虽然我找不到答案):

有没有抽象类的实际例子 声明为 Abstract 的方法?

在大多数情况下,正如 Java 教程中提到的,具有所有抽象方法的类应该是一个接口。

但是由于抽象类和接口是两个不同的概念,我正在寻找一个具有“完整抽象类”的例子

【问题讨论】:

  • 区别是restricting visibility

标签: java inheritance interface abstract


【解决方案1】:

我认为唯一实用的方法是Abstract class 可以保持状态。因此,您可以拥有访问级别为protected 的内部属性,并且您可以将protected abstract methods 设置为在界面中您不能导致所有都是public

一个实际的例子可能是这样,java中的受保护方法具有“继承访问”和“包访问”。

public interface Operation{
void operate();
} 

public abstract class AbstractClase implements Operation{
 protected Operation delegate;

 public AbstractClase(Operation delegate){
  this.delegate=delegate;
 }

 //delegate implementation responsability to children
 protected abstract doSomething();

}

使用抽象类的缺点是你也失去了扩展其他东西的可能性。

【讨论】:

    【解决方案2】:

    除了保持状态,值得记住的是所有接口成员都隐含public。因此,限制抽象方法的可见性本身可能是使用抽象类而不是接口的一个足够令人信服的理由。

    【讨论】:

      【解决方案3】:
      1. 除了上面给出的两个答案之外,接口只能有常量(变量是公共的、静态的和最终的),而抽象类没有这样的限制。

      2. 抽象类可以有构造函数,当子类被实例化时(如果它是非参数化的),这些构造函数将被隐式调用。但这对于接口是不可能的。

      这是一个抽象类的使用示例

      abstract class Animal{
          public int noOfLegs;
          public boolean isAlive;
          Animal(){
              isAlive = true;
          }
          public abstract void walk();
      }
      class Cow extends Animal{
          Cow(){
              noOfLegs = 4;
          }
          public void walk(){
              if(isAlive){
                  //Code for walking   
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        抽象类的另一个通用目的是防止类的实例。例如

         abstract class Mammal{
           int i=0;
         }
         public class Man extends Mammal{
            public setMeValue(int i){
               this.i=i;
        
            }
        public static void main(String args[]){
           Mammal m= new Man();
           man.setMeValue(10);
         }
         }
        

        在上面的代码中,我有效地确保永远不会有实例 Mammal 的对象。

        【讨论】:

        • 这很好,它没有回答为什么一个类的所有方法都是抽象的。
        • Abstract 类不支持多重继承,例如上面的代码中,如果你想防止 Man 扩展出 Mammal 和爬虫类,你可以通过确保 Mammal 是一个抽象来有效地防止它类。
        【解决方案5】:

        一个接口可以应用于非常不同的类。彼此没有关系的类是SerializableCloneable。但是,抽象类的子类都是相关的。这在实现接口或扩展抽象类时可能没有任何意义,但它在语义上是有意义的。

        有一种编程风格,其中基类的所有方法要么是public finalprotected abstractprotected 和空,要么是private。但这也不是 OP 感兴趣的。

        【讨论】:

          【解决方案6】:

          在以下答案中添加更多内容:

          接口为你提供了一个实现的契约,抽象类也可以为你提供一个模板。对于一个简单的场景,您可以使用接口或抽象类而无需考虑太多。但是拥有一个仅用于维护状态的抽象类可能会给您在复杂的实现中带来很多问题。在这种情况下,您必须仔细考虑您真正想在代码中实现什么并做出决定。如果您考虑在代码中维护状态的情况,您始终可以在实现中使用State pattern,这样您就可以在代码中使用接口。在决定使用抽象类而不是接口之前,您应该始终考虑代码的可扩展性和可维护性。

          【讨论】:

            【解决方案7】:

            我能想到的最简单的实际示例是具有受保护变量的类:

            public abstract class RoadVehicle {
                protected int numberOfTires;
                protected String vinNumber;
                protected VehicleRegistration registration;
                public abstract void drive();
                public abstract double calculateToll();
                public abstract void changeTires();
                // so on and so forth...
            }
            

            你不能用接口来做到这一点。

            【讨论】:

            • 没有意义 numberOftires is inaccesible
            • @nachokk - 哎呀...受保护是我的意思。愚蠢的错误:-0
            【解决方案8】:
            public abstract class animal{
                public abstract void speak(){
                    System.out.println("animal voice");
                }
            }
            
            public class dog extends animal{
                public void speak(){
                    System.out.println("dog voice");
                }
            }
            

            【讨论】:

            • 不确定这个例子与问题的相关性有多大
            【解决方案9】:

            拥有纯抽象类的最大动机是允许未来扩展。假设您有一个抽象类(具有所有抽象成员),然后您在 20 个派生类中继承该抽象类。将来某个时候,您希望为您的 5 个派生类添加一个公共方法,您会怎么做?


            由于您已经继承了抽象类,一个更简单的解决方案是将方法 (with implementation) 添加到抽象类。这样您就不必接触任何派生类。在这种情况下,接口非常严格,一旦创建,就几乎没有机会更改接口,因为它需要更改实现该接口的所有类。

            【讨论】:

              猜你喜欢
              • 2015-10-06
              • 2011-07-10
              • 1970-01-01
              • 2023-03-03
              • 2023-03-10
              • 2019-10-06
              • 2020-06-20
              • 2020-03-12
              相关资源
              最近更新 更多