Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 接口的意图与带有抽象方法的抽象类有何不同? 解释/序言_Java_Interface_Abstract Class - Fatal编程技术网

Java 接口的意图与带有抽象方法的抽象类有何不同? 解释/序言

Java 接口的意图与带有抽象方法的抽象类有何不同? 解释/序言,java,interface,abstract-class,Java,Interface,Abstract Class,在Java中,如果使用抽象方法声明抽象类,例如 public abstract class MyAbstractClass { private String m_id; // default behavior public MyAbstractClass() { setId(null); } public String getId() { return m_id; } public void setId(String id) { m_id = id; } //

在Java中,如果使用抽象方法声明抽象类,例如

public abstract class MyAbstractClass {
  private String m_id;
  
  // default behavior
  public MyAbstractClass() { setId(null); }
  public String getId() { return m_id; }
  public void setId(String id) { m_id = id; }
  
  // overridenable method
  public void doSomething() { /* does nothing by default */ }
  
  // to-be-defined behavior
  public abstract void setSomething(Object o);
  public abstract Object getSomething();
}
public class MyClass extends MyAbstractClass {
  private Object m_o;
  
  // implements some actual complex behavior
  public void setSomething(Object o) { m_o = o; }
  public Object getSomething() { return m_o; }
}
您可以有效地声明一个具有“默认行为”排序的类(用于
m_id
的getter和setter),并强制该类由必须实现“缺少”(抽象)方法的子类实例化,例如

public abstract class MyAbstractClass {
  private String m_id;
  
  // default behavior
  public MyAbstractClass() { setId(null); }
  public String getId() { return m_id; }
  public void setId(String id) { m_id = id; }
  
  // overridenable method
  public void doSomething() { /* does nothing by default */ }
  
  // to-be-defined behavior
  public abstract void setSomething(Object o);
  public abstract Object getSomething();
}
public class MyClass extends MyAbstractClass {
  private Object m_o;
  
  // implements some actual complex behavior
  public void setSomething(Object o) { m_o = o; }
  public Object getSomething() { return m_o; }
}
甚至可能重写超类中的方法

因此,似乎一个带有抽象方法的抽象类的行为就好像它是一个
接口一样

public interface IMy {
  public void setSomething(Object o);
  public Object getSomething();
}
因为要使用它,它最终必须指向一个实际的对象

问题 在现有的
接口
抽象类
——以及抽象方法(ACWAM)中,这几乎似乎毫无意义,因为它们看起来非常相似

  • ACWAM看起来非常类似于
    接口
    !我想本质的区别在于他们的意图
  • 据我所知,
    界面
    旨在提供一种方式,使图书馆用户可以在不依赖图书馆实施的情况下与图书馆“交谈”。
    接口
    旨在“向公众展示”,而ACWAM旨在让库开发人员“同意”,但提供默认(覆盖)行为的“额外好处”,这是正确的解释吗
  • 与ACWAM同时使用
    接口
    有意义吗

  • 您能否提供一个或两个简单的示例(指向另一个文档就可以了)来说明这两个方面的意图差异(或“良好使用”),即
    接口和ACWAM?

    Java不支持多重继承。因此,一个类可以实现许多接口,但不能从多个基类继承。

    abstract类使用一些/所有抽象方法。 但接口是所有抽象方法的接口

    在senarios中,所有方法都是抽象的,然后选择如下界面:

    interface City
    {
       public void pin();
       public void state();
    }
    
    任何城市都必须为这两种抽象方法提供自己的实现

    例:

    但让我们举个例子:在这样的场景中,一些方法对于扩展该类的类是通用的,但有些方法必须给出不同的实现:

    abstract class Animal{
      public abstract void eat();
    
      public void run()
      {
         System.out.println("I can Run");
      } 
    
    }
    
    假设Dog和Cat都扩展了这个抽象类。它们都将从类Animal继承相同的run()

    class Dog extends Animal
    {
        public void eat()
        {
           System.out.println("I eat Meat");
        }
    }
    
    class cat extends Animal
    {
        public void eat()
        {
           System.out.println("I eat only Fish");
        }
    }
    

    接口和抽象类之间的最大区别是:

    • 抽象类将“是”关系强加给实现。您必须对抽象类进行子类化。您将永远被绑定到特定的类层次结构中
    • 接口将“看起来像”关系强加给实现。您可以将任何您喜欢的东西子类化,只要它遵守接口。这使你可以在任何你喜欢的课程中进行交换。如果有更好的,这一点尤其有用
    一个很好的工作规则是API应该总是引用接口

    请注意,JDK中充斥着早期使用(抽象)类时所犯的错误,而这些类本应使用接口。这是一个很好的例子:堆栈应该是一个接口,但它是一个类。如果您想实现自己的堆栈,那么必须创建java.util.Stack子类,这是非常规范的-您可能不想这样做-也许您需要一个超轻量级的版本等等


    然而,抽象类确实有自己的位置:它们可以提供接口的默认实现。一个很好的例子是,一个类是接口的框架实现。

    如果有帮助,可以将Java接口视为契约,将Java抽象类视为模板。

    如果必须在接口和仅使用抽象方法的抽象类之间进行选择,则应选择接口,因为它为以后提供了更多的可能性:可以有多个接口,但只能有一个抽象类


    如果您需要一些常见行为,您也可以选择接口,因为您可以通过在具体类中组合来获得常见行为(并且您可以受益于多重继承)。

    请不要使用“Dog extends Animal”示例,它只是让人困惑。+1,另外值得一提的是,在
    Java
    中,不能从多个类继承。因此,误用抽象类而不是接口可能导致没有扩展。