Java 转换为抽象类…这怎么可能?
我实际上正在读一本关于java设计模式的书,我是一个新手:) 在关于复合模式的章节中,我遇到了一个让我困惑的代码,一个对抽象类的转换,我也不太理解子类调用抽象超类的构造函数时会发生什么,你能帮我吗 我所说的演员阵容在iTree中(已访问场景) 在对子类的抽象超类进行转换之后,我们如何调用子类的Java 转换为抽象类…这怎么可能?,java,inheritance,abstract-class,Java,Inheritance,Abstract Class,我实际上正在读一本关于java设计模式的书,我是一个新手:) 在关于复合模式的章节中,我遇到了一个让我困惑的代码,一个对抽象类的转换,我也不太理解子类调用抽象超类的构造函数时会发生什么,你能帮我吗 我所说的演员阵容在iTree中(已访问场景) 在对子类的抽象超类进行转换之后,我们如何调用子类的isTree方法 而isTree超类方法是抽象的 以下是两个类的片段: package com.oozinoz.machine; /* * Copyright (c) 2001, 2005. Steven
isTree
方法
而isTree
超类方法是抽象的
以下是两个类的片段:
package com.oozinoz.machine;
/*
* Copyright (c) 2001, 2005. Steven J. Metsker.
*/
import java.util.*;
import com.oozinoz.iterator.ComponentIterator;
/**
* Objects of this class represent either individual machines or composites of
* machines.
*/
public abstract class MachineComponent {
/*
* Subclasses implement this to support the isTree() algorithm.
*/
protected abstract boolean isTree(Set s);
// rest of class omitted
}
2:
问:你能转换成一个抽象类吗 当然可以,当然可以
您不能做的是调用抽象类的抽象方法。(从下面的注释部分插入-Andrew Barber)-您实际上是在子类中调用它的具体实现 好吧,让我们看一下
Cat
,它是抽象类Animal
的一个子类
你可以将猫投给动物,因为猫是动物。它做正常动物所做的一切,因为它具有动物的功能
子类化一个抽象类是相同的。您可以简单地使用“is a”,因为它是一个子类
你可以将动物列表定义为动物园,但它可以有狗和猫——毕竟,它们都是动物
将一只猫
扔给一只动物
实际上并不会使它比以前更像一只猫
——你只需告诉你的代码对待它就像对待任何其他动物一样
编辑如果你不喜欢猫(我也不喜欢),让我把你引向另一个方向。如果不能强制转换抽象类,那么抽象类将毫无用处。isTree只是抽象类的抽象。一旦类被初始化为非抽象类,将其转换为抽象类不会改变其内存。因此,在抽象类上调用该方法可以有效地在具体实现上调用它 它之所以有用,是因为它通过抽象实现传递子类
假设String类具有“length”方法。没有必要为每个可能的字符串类型子类都提供一个函数。相反,您可以强制转换到具有“length”实现的基本(抽象)字符串,并传递它。这是运行时类型(实际类型)和编译时类型之间的区别 对抽象类
MachineComponent
的类型转换是可以的,因为实际的对象实例实际上是实现所有抽象方法的MachineComponent
的一些非抽象子类
抽象MachineComponent
类是指定变量的编译时类型。但没有(或可以)使用该抽象类创建实际实例 好的-让我们再试一次:
问:你能转换成一个抽象类吗 当然可以,当然可以 例如:
public class UseAbstract
{
public static void main (String[] args)
{
// Instantiate an abstract class
AbstractPet myDog = new Dog ();
myDog.sound ();
// Instantiate a concrete class
Cat myCat = new Cat ();
myCat.sound ();
// Cast a concrete class to an abstract class
AbstractPet somePet = (AbstractPet)myCat;
somePet.sound ();
}
}
abstract class AbstractPet
{
void sound ()
{
System.out.println ("eek");
}
}
class Dog extends AbstractPet
{
void sound ()
{
System.out.println ("Woof");
}
}
class Cat extends AbstractPet
{
void sound ()
{
System.out.println ("meow");
}
}
是的……完全不是真的。@mre,这有什么不对的?一个抽象方法没有代码,所以你会调用什么?这是真的,但我可以看出,如果一些人对术语的挑剔与回答者不同,他们可能不会这么认为。如果你认为你在调用抽象函数,那么你实际上是在子类中调用它的具体实现。@Paul,对我来说,这个答案似乎是说不可能调用抽象类的抽象方法,这一点都不正确。如果要将整个文件转储到中,请正确设置代码格式。@wrscheider99-完全正确。事实上,这就是抽象类的定义——它是一个不能为其创建任何具体实例的类——为了创建具体实例,必须为其创建子类。坦率地说,“接口”在Java中往往非常非常有用。但是抽象类在很多情况下都很重要,包括OP的例子。
package com.oozinoz.machine;
/*
* Copyright (c) 2001, 2005. Steven J. Metsker.
*/
import java.util.*;
import com.oozinoz.iterator.ComponentIterator;
import com.oozinoz.iterator.CompositeIterator;
/**
* Represent a collection of machines: a manufacturing line, a bay, or a
* factory.
*/
public class MachineComposite extends MachineComponent {
protected List components = new ArrayList();
/**
* @param visited a set of visited nodes
* @return true if this composite is a tree
* @see MachineComponent#isTree()
*/
protected boolean isTree(Set visited) {
visited.add(this);
Iterator i = components.iterator();
while (i.hasNext()) {
MachineComponent c = (MachineComponent) i.next();
if (visited.contains(c) || !c.isTree(visited))
return false;
}
return true;
}
// rest of class omitted
}
public class UseAbstract
{
public static void main (String[] args)
{
// Instantiate an abstract class
AbstractPet myDog = new Dog ();
myDog.sound ();
// Instantiate a concrete class
Cat myCat = new Cat ();
myCat.sound ();
// Cast a concrete class to an abstract class
AbstractPet somePet = (AbstractPet)myCat;
somePet.sound ();
}
}
abstract class AbstractPet
{
void sound ()
{
System.out.println ("eek");
}
}
class Dog extends AbstractPet
{
void sound ()
{
System.out.println ("Woof");
}
}
class Cat extends AbstractPet
{
void sound ()
{
System.out.println ("meow");
}
}