为什么可以转换为抽象类
我正在读一本关于java数据结构的书,现在正在谈论迭代器。我看到下面的代码,我觉得很奇怪。在下面的代码中,AbstractIterator
是一个实现了Iterator
的抽象类,UniqueFilter
是AbstractIterator
的子类> 这不是抽象的,data
是一个 Vector。我想我不明白如何在第一行中获取 Vector.iterator() 方法的输出并将其转换为抽象类。第 1 行之后,dataIterator 不是抽象类的实例化实例吗?
AbstractIterator<String> dataIterator =
(AbstractIterator<String>)data.iterator();
AbstractIterator<String> ui = new UniqueFilter(dataIterator);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
问题是我们正在谈论两种不同的类型。对象的(运行时)类型和引用的(编译时)类型。
dataIterator
是抽象类型的引用 - 没关系。data.iterator()
返回对示例中其类型不清楚的对象的引用,但显然它是继承自AbstractIterator
的具体类型 - 没关系因此,在第一行之后,
dataIterator
仍然是AbstractIterator
类型的引用,但它是对实现AbstractIterator
的具体类型对象的引用。 。请记住,在 JAVA 中,所有对象变量实际上都是引用。
顺便说一句,
UniqueFilter
与这个问题无关。The problem is that there are two different types we are talking about. The (run time) type of an object and the (compile time) type of a reference.
dataIterator
is a reference of an abstract type - that's ok.data.iterator()
returns a reference to an object whose type is not clear from the example, but apparently it's a concrete type which inherits fromAbstractIterator<String>
- that's okSo after line one
dataIterator
is still a reference of typeAbstractIterator<String>
, but it's a reference to an object of a concrete type which implementsAbstractIterator<String>
.Remember, in JAVA all the object variables are actually references.
UniqueFilter
is irrelevant for this question, btw.继承意味着 IS-A。如果子级继承自父级,则子级就是父级,并且可以在任何需要父级的情况下使用。
由于
UniqueFilter
IS-AAbstractIterator
,这意味着您可以像代码所示那样对其进行转换。为什么你不相信 JVM?
Inheritance means IS-A. If a Child inherits from a Parent, then Child IS-A Parent and can be used in any situation where a Parent is called for.
Since
UniqueFilter
IS-AAbstractIterator
, this means you can cast it just as your code shows.Why would you not believe the JVM?
第 1 行之后,dataIterator 不是抽象类的实例化实例吗?
它是
UniqueFilter
的一个实例,也通过继承使其成为AbstractIterator
。尝试“实例化抽象类的实例”意味着尝试调用抽象类的构造函数,这是不允许的,也是这里不会发生的情况。After line 1, is
dataIterator
not an instantiated instance of an abstract class?It is an instance of a
UniqueFilter
which also makes it anAbstractIterator
by inheritance. Attempting to "instantiate and instance of an abstract class" means attempting to call the abstract class' constructor, that's what's not allowed, and that's what's not happening here.抽象类是无法实例化的类。通常它会包含一个或多个也被声明为抽象的方法,并且必须由子类实现才能使子类具体化(与抽象相反),因此能够被实例化。
UniqueFilter
是AbstractIterator
(抽象类)的子类。由于这是一种 IS-A 类型的关系,因此您无法声明抽象类的实例。如果要为抽象类创建实例,首先创建一个具体子类并为其创建一个实例并使用它。
Abstract Class is a class that cannot be instantiated. Often it will include one or more methods that are also declared abstract and must be implemented by subclasses for the subclass to be concrete (opposite of abstract), and therefore able to be instantiated.
UniqueFilter
is a subclass ofAbstractIterator
( an abstract class). Since this is aIS-A
kind of relationship, you cannot declare an instance of abstract class.If you want to create an instance for abstract class, first you create a concrete subclass and create an instance for that and use it.
从你的描述来看,似乎有一个可以做出的假设被忽视了;这里
data.iterator()
返回的实现类型是AbstractIterator
的子类。如果可以做出这个假设,那么第一个语句就变得显而易见,因为对象可以合法地类型转换为继承层次结构中的任何对象,在本例中为
AbstractIterator
。在这种情况下,dataIterator 不是抽象类的实例化实例;而是抽象类的实例化实例。它没有在这里实例化(即 new AbstractIterator),它只是对
Vector.iterator()
返回的实例化实例的引用,其类型为是实际返回类型的超类,它恰好是一个抽象类。From what you've described it looks like there's an assumption that can be made that has been overlooked; that the implementing type returned by
data.iterator()
here is a subclass ofAbstractIterator<String>
.If this assumption can be made, then the first statement becomes obvious as an object can be legally type cast to any object up the inheritance hierarchy, in this case an
AbstractIterator<String>
.In this case
dataIterator
is NOT an instantiated instance of an abstract class; its not being instantiated here (i.enew AbstractIterator<String(...)
), its just a reference to the instantiated instance returned byVector.iterator()
with the type being that of a superclass of the actual returned type, which happens to be an abstract class.HeadofState 是一个抽象术语(抽象一词的英文含义)。
世界上没有一个国家的国家元首的正式头衔是Head-of-State。
国家元首,尽管在语言和存在上是抽象的,但却是诸如苏丹、总统、总理、总理、敬爱的父亲等头衔的超类或超类别。
因此,即使元首的存在——国家不能以抽象形式实例化,但你可以实例化(通过民主手段、世袭或政变)总统、总理或任何大人物。
也就是说,总理已经被实例化,那么它就可以等同于其抽象父术语“国家元首”。
因此,即使无法实例化抽象类,也可以实例化该抽象类的实现。这就是工厂可以做的事情。工厂是创建抽象类实例的一种方法。
就像抽象类一样,接口不能被实例化,但必须被实现。抽象类是部分实现的,而接口本身是完全未实现的。抽象类和接口依赖派生类来完成其存在。当然,痴迷的 OO 纯粹主义者的技术术语会澄清抽象类是“扩展的”而接口是“继承的”。
例如,HttpServletRequest 就是一个接口。您不能直接实例化它。当您的 JSP 获取其 http servlet 请求时,无论您是在 Jetty 还是 Tomcat 中,它的工作方式都是相同的。但是,如果仔细检查,Jetty 中 HttpServletRequest 工厂实例化的实际类与 Tomcat 中创建的类不同。但是,由于它们都实现了 HttpServletRequest,因此这些实例可以简单地等同于类型为 HttpServletRequest 的变量。
您应该阅读抽象类与接口以及如何构造接口以允许 Java 中的伪多重继承。一旦理解了接口的作用,您就会理解抽象类。在面向对象的激烈争论中,有些人认为接口是多重继承的一次辉煌突破。有些人认为接口与多重继承无关。在我自己不太谦虚的观点中,界面是社会主义家长式放纵的一次糟糕而失败的尝试,目的是防止我陷入假定我不知道如何照顾自己的麻烦。
HeadofState is an abstract (by the English meaning of the word abstract) term.
There is no country in the world where the official title of its head-of-state is Head-of-State.
A head-of-state, even though abstract in language and existence, is a super class or super category of titles like sultan, president, premier, prime minister, beloved father, etc.
So, even though the existence of head-of-state cannot be instantiated in its abstract form, you can instantiate (by democratic means, hereditary or by coup) a president, a prime minister, or any honcho-what-nots.
So say, a prime minister has been instantiated, it can then be equated to its abstract parent terminology of "Head-of-State".
So even though an abstract class cannot be instantiated, an implementation of that abstract class can be instantiated. That is what factories can do. Factories are a means to create instances of abstract classes.
Just like abstract classes, interfaces cannot be instantiated but must be implemented. Abstract classes are partially implemented, whereas interfaces are totally unimplemented by themselves. Abstract classes and interfaces depends on derivative classes to complete their existence. Of course, the obsessive OO-purist's technical terminology would clarify that abstract classes are "extended" and interfaces are "inherited".
For example, HttpServletRequest is an interface. You cannot instanstiate it directly. When your JSP grabs its http servlet request, it works the same whether you are in Jetty or Tomcat. However, if you inspect carefully, the actual class instantiated by the HttpServletRequest factory in Jetty is different from that created in Tomcat. But, since both of them implement HttpServletRequest, those instances can simply be equated to a variable whose type is HttpServletRequest.
You should read up on abstract classes vs interfaces and how interfaces are concocted to allow pseudo-multiple inheritance in Java. Once you understand the role of interfaces, you would then understand abstract classes. In the realm of object-oriented flame wars, some people think that Interfaces was a brilliant break-thro in multiple inheritance. Some people think interfaces have nothing to do with multiple inheritances. In my own less than humble opinion, interfaces are a poor and failed attempt at socialist's paternalistic indulgence to prevent me from getting into trouble that presumes that I don't know how to take care of myself.