最近在一次采访中,我被问到一个非常笼统的问题“java中的抽象是什么”。我给出了定义,然后在抽象方面跟随了一些其他问题,抽象方法和抽象方法与具体方法之间的区别和等等 然后最后面试官要求给出一个实时的例子,当我应该使用或定义一个类作为抽象时。我感到困惑。我举了一些例子,但他不相信。
我用Google搜索但没有找到真正的解决方案。
那么有人可以给我实时的例子,即他在他/她的项目中将课程定义为抽象的时候以及为什么?
感谢。
答案 0 :(得分:21)
从here找到实时的一个很好的例子: -
抽象类的一个具体示例是一个名为的类 动物。你在现实生活中看到很多动物,但只有种类 动物。也就是说,你永远不会看到紫色和毛茸茸的东西说 “这是一种动物,没有更具体的方法来定义它”。 相反,你会看到一只狗,一只猫或一只猪......所有的动物。重点是, 你永远看不到一只动物走来走去的东西并不多 特别是别的东西(鸭子,猪等)。动物是 抽象类和Duck / Pig / Cat都是源自它的类 基类。动物可能会提供一个名为“Age”的函数,它会增加1 动物的一生。它也可能提供一种抽象方法 叫做“IsDead”,当被叫时,会告诉你动物是否有 死了。由于IsDead是抽象的,每只动物都必须实现它。所以,一个 猫可能会在它达到14岁后判定它死了,但是a Duck可能会认为它在5岁后死亡。抽象类 Animal为从它派生的所有类提供Age函数, 但是每个类都必须自己实现IsDead。
商家example:
我有一个可以对抗任何数据源的持久性引擎 (XML,ASCII(分隔和固定长度),各种JDBC源 (Oracle,SQL,ODBC等)我创建了一个基类,抽象类来提供 这个持久性中的常见功能,但是实例化了 持久化我的对象时适当的“端口”(子类)。 (这使得 由于大部分工作已经完成,因此新“港口”的开发变得更加容易 在超级班;特别是各种JDBC;既然我没有 我只有做坚持但其他事情[比如桌子生成] 为每个数据库提供各种差异。)最好的 接口的业务示例是集合。我可以用一个 java.util.List,不关心它是如何实现的;有名单 作为一个抽象类没有意义,因为有根本 anArrayList如何工作而不是LinkedList的差异。 同样,Map和Set。如果我只是和一群人一起工作 对象并不关心它是List,Map还是Set,我可以使用 收集界面。
答案 1 :(得分:4)
这里,关于抽象类的东西......
实时示例 -
如果你想制造一辆新车(WagonX),其中包括所有其他车的属性,如颜色,尺寸,引擎等,你想在你的车中添加一些其他功能,如型号,baseEngine。然后只是你创建一个抽象类WagonX,其中您使用所有预定义的功能作为抽象,而另一个功能是具体的,由您定义。
扩展抽象类WagonX的另一个子类,默认情况下它还访问抽象类中实例化的抽象方法.SubClasses也通过创建子类的对象来访问具体方法。
为了代码的可重用性,开发人员主要使用抽象类。
abstract class WagonX
{
public abstract void model();
public abstract void color();
public static void baseEngine()
{
// your logic here
}
public static void size()
{
// logic here
}
}
class Car extends WagonX
{
public void model()
{
// logic here
}
public void color()
{
// logic here
}
}
答案 2 :(得分:3)
抽象类的最佳示例是GenericServlet
。 GenericServlet
是HttpServlet
的父类。这是一个抽象类。
在自定义servlet类中继承'GenericServlet'时,必须覆盖service()
方法。
答案 3 :(得分:2)
您应该能够引用JDK本身中的至少一个。查看java.util.collections
包。有几个抽象类。你应该完全理解Map
的界面,抽象和具体,以及Joshua Bloch为什么这样写的。
答案 4 :(得分:0)
我常常将抽象类与Template method pattern结合使用
在主要的抽象类中,我编写了主要算法的框架,并将抽象方法作为钩子,其中suclasses可以进行特定的实现;我经常在编写需要从一个不同的地方(文件,数据库或其他来源)读取数据的数据解析器(或处理器)时,经常使用类似的处理步骤(可能是小的差异)和不同的输出。
这种模式看起来像Strategy pattern,但是如果主代码增长太多或者需要太多主流异常(这些考虑来自我的经验),它会减少粒度,并且可以降级为难以编辑的代码。
只是一个小例子:
abstract class MainProcess {
public static class Metrics {
int skipped;
int processed;
int stored;
int error;
}
private Metrics metrics;
protected abstract Iterator<Item> readObjectsFromSource();
protected abstract boolean storeItem(Item item);
protected Item processItem(Item item) {
/* do something on item and return it to store, or null to skip */
return item;
}
public Metrics getMetrics() {
return metrics;
}
/* Main method */
final public void process() {
this.metrics = new Metrics();
Iterator<Item> items = readObjectsFromSource();
for(Item item : items) {
metrics.processed++;
item = processItem(item);
if(null != item) {
if(storeItem(item))
metrics.stored++;
else
metrics.error++;
}
else {
metrics.skipped++;
}
}
}
}
class ProcessFromDatabase extends MainProcess {
ProcessFromDatabase(String query) {
this.query = query;
}
protected Iterator<Item> readObjectsFromSource() {
return sessionFactory.getCurrentSession().query(query).list();
}
protected boolean storeItem(Item item) {
return sessionFactory.getCurrentSession().saveOrUpdate(item);
}
}
Here另一个例子。