为什么你可以转换为抽象类

时间:2011-06-12 01:54:52

标签: java inheritance abstract-class

我正在读一本关于java中数据结构的书,现在正在谈论迭代器。我看到下面的代码,对我来说似乎很奇怪。在以下代码中,AbstractIterator是实现Iterator<E>的抽象类,UniqueFilterAbstractIterator的子类,不是抽象的,data是Vector 。我想我不明白你在第一行中如何获取Vector.iterator()方法的输出并将其转换为抽象类。在第1行之后,dataIterator不是抽象类的实例化实例吗?

AbstractIterator<String> dataIterator =
    (AbstractIterator<String>)data.iterator();
AbstractIterator<String> ui = new UniqueFilter(dataIterator);

6 个答案:

答案 0 :(得分:3)

问题是我们正在谈论两种不同的类型。对象的(运行时)类型和引用的(编译时)类型。

  1. dataIterator是抽象类型的引用 - 没关系。
  2. data.iterator()返回对该示例中类型不明确的对象的引用,但显然它是继承自AbstractIterator<String>的具体类型 - 这没关系
  3. 如果B是A的子节点,即使A是抽象(或接口),也可以始终将对类型B的对象的引用分配给对类型A的对象的引用。你实际上不需要演员。
  4. 因此,第一行dataIterator仍然是类型AbstractIterator<String>的引用,但它是对实现AbstractIterator<String>的具体类型的对象的引用。

    请记住,在JAVA中,所有对象变量实际上都是引用。

    UniqueFilter与此问题无关,顺便说一句。

答案 1 :(得分:0)

继承意味着IS-A。如果Child继承自Parent,则Child IS-A Parent可以在任何需要Parent的情况下使用。

UniqueFilter IS-A AbstractIterator以来,这意味着您可以像代码所示一样投出它。

为什么你不相信JVM?

答案 2 :(得分:0)

抽象类 是一个无法实例化的类。它通常包含一个或多个也被声明为抽象的方法,并且必须由子类实现,以使子类具体化(与抽象相反),因此能够实例化。

UniqueFilterAbstractIterator(抽象类)的子类。由于这是一种IS-A种关系,因此您无法声明抽象类的实例。

如果要为抽象类创建实例,首先要创建一个具体的子类并为其创建一个实例并使用它。

答案 3 :(得分:0)

在第1行之后,dataIterator是否不是抽象类的实例化实例?

它是UniqueFilter的一个实例,它也通过继承使其成为AbstractIterator。尝试“实例化和抽象类的实例”意味着尝试调用抽象类的构造函数,这是不允许的,这就是这里没有发生的事情。

答案 4 :(得分:0)

从你所描述的内容来看,似乎有一个假设可以被忽略;这里data.iterator()返回的实现类型是AbstractIterator<String>的子类。

如果可以做出这样的假设,那么第一个语句变得显而易见,因为对象可以合法地类型转换为继承层次结构中的任何对象,在本例中为AbstractIterator<String>

在这种情况下,dataIterator不是抽象类的实例化实例;它没有在这里实例化(即new AbstractIterator<String(...)),它只是对Vector.iterator()返回的实例化实例的引用,其类型是实际返回类型的超类,它恰好是一个抽象类

答案 5 :(得分:0)

HeadofState是一个摘要(由摘要一词的英文含义)术语。

世界上没有哪个国家的国家元首的官方头衔是国家元首。

一个国家元首,即使在语言和存在方面都是抽象的,也是苏丹,总统,总理,总理,亲爱的父亲等超级或超级类别的头衔。

所以,即使国家元首的存在不能以抽象的形式实例化,你也可以(通过民主手段,遗传或政变)实例化总统,总理或任何不可思议的事物。

所以说,总理已被实例化,然后可以将其等同于其“国家元首”的抽象母语术语。

因此,即使无法实例化抽象类,也可以实例化该抽象类的实现。这就是工厂可以做的事情。工厂是一种创建抽象类实例的方法。

就像抽象类一样,接口无法实例化,但必须实现。抽象类是部分实现的,而接口完全没有实现。抽象类和接口依赖于派生类来完成它们的存在。当然,强迫性的OO-purist的技术术语将阐明抽象类是“扩展”的,接口是“继承的”。

例如,HttpServletRequest是一个接口。你不能直接实现它。当你的JSP获取其http servlet请求时,无论你是在Jetty还是Tomcat,它的工作方式都是一样的。但是,如果仔细检查,由Jetty中的HttpServletRequest工厂实例化的实际类与Tomcat中创建的类不同。但是,由于它们都实现了HttpServletRequest,这些实例可以简单地等同于一个类型为HttpServletRequest的变量。

您应该阅读抽象类和接口以及如何编写接口以允许Java中的伪多重继承。一旦理解了接口的作用,就可以理解抽象类。在面向对象的火焰战争领域,有些人认为Interfaces是多重继承中的一个突破性的突破。有些人认为接口与多重继承无关。在我自己不那么谦虚的意见中,接口是社会主义者的家长式放纵的一种贫穷和失败的尝试,以防止我陷入麻烦,假设我不知道如何照顾自己。