Java 接口的意图与带有抽象方法的抽象类有何不同? 解释/序言
在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; } //
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
中,不能从多个类继承。因此,误用抽象类而不是接口可能导致没有扩展。