Java中的“抽象类”是什么?
当前回答
类,它可以有具体方法和非具体方法,即有主体和没有主体。
没有实现的方法必须包含'abstract'关键字。 抽象类不能被实例化。
其他回答
抽象类是不能被实例化的类。抽象类是通过创建可实例化的继承子类来使用的。抽象类为继承的子类做了一些事情:
定义可由继承子类使用的方法。 定义继承子类必须实现的抽象方法。 提供一个公共接口,允许子类与所有其他子类交换。
这里有一个例子:
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
注意,“abstractMethod()”没有任何方法主体。因此,你不能做以下事情:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
没有实现abstractMethod()的方法!因此,当JVM获得像new ImplementingClass(). abstractmethod()这样的东西时,它无法知道应该做什么。
这是一个正确的实现类。
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
注意,您不必定义implementedMethod()或finalMethod()。它们已经由AbstractClass定义。
这是另一个正确的ImplementingClass。
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
在本例中,您重写了implementedMethod()。
但是,由于final关键字,不能执行以下操作。
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
public void finalMethod() { System.out.print("ERROR!"); }
}
您不能这样做,因为AbstractClass中finalMethod()的实现被标记为finalMethod()的最终实现:不允许任何其他实现。
现在你还可以实现一个抽象类两次:
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("second abstractMethod()"); }
}
现在你可以在某处写另一个方法。
public tryItOut()
{
ImplementingClass a = new ImplementingClass();
AbstractClass b = new ImplementingClass();
a.abstractMethod(); // prints "abstractMethod()"
a.implementedMethod(); // prints "Overridden!" <-- same
a.finalMethod(); // prints "finalMethod()"
b.abstractMethod(); // prints "abstractMethod()"
b.implementedMethod(); // prints "Overridden!" <-- same
b.finalMethod(); // prints "finalMethod()"
SecondImplementingClass c = new SecondImplementingClass();
AbstractClass d = new SecondImplementingClass();
c.abstractMethod(); // prints "second abstractMethod()"
c.implementedMethod(); // prints "implementedMethod()"
c.finalMethod(); // prints "finalMethod()"
d.abstractMethod(); // prints "second abstractMethod()"
d.implementedMethod(); // prints "implementedMethod()"
d.finalMethod(); // prints "finalMethod()"
}
注意,尽管我们将b声明为AbstractClass类型,但它显示为“override !”。这是因为我们实例化的对象实际上是一个ImplementingClass,它的implementedMethod()当然被重写了。(您可能已经看到这被称为多态。)
如果希望访问特定于特定子类的成员,必须先向下转换到该子类:
// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();
最后,你不能做以下事情:
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
一次只能扩展一个类。如果需要扩展多个类,则它们必须是接口。你可以这样做:
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
下面是一个接口示例:
interface InterfaceA
{
void interfaceMethod();
}
这基本等同于:
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
唯一的区别是第二种方法不会让编译器知道它实际上是一个接口。如果你想让人们只实现你的接口而不实现其他接口,这可能很有用。然而,作为初学者的经验法则,如果你的抽象类只有抽象方法,你可能应该让它成为一个接口。
以下行为是非法的:
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
不能在接口中实现方法。这意味着如果实现两个不同的接口,这些接口中的不同方法不能冲突。由于接口中的所有方法都是抽象的,因此必须实现该方法,并且由于您的方法是继承树中唯一的实现,因此编译器知道它必须使用您的方法。
除了这些帖子之外。
有时你可能想声明一个 类,但不知道如何定义 所有的方法都属于这个 类。例如,你可能想要 声明一个名为Writer和的类 在它中包含一个名为 写()。但是,您不知道如何编写write()代码,因为它就是 每种类型的作者都不一样 设备。当然,你打算处理 通过派生Writer的子类, 如打印机,磁盘,网络和 控制台。
什么是抽象类? 好的!让我们举个例子,你对化学了解不多,我们有一个元素碳(符号C)。碳有一些基本的原子结构,你不能改变,但用碳你可以制造很多化合物,如(CO2),甲烷(CH4),丁烷(C4H10)。
所以这里碳是抽象类,你不想改变它的基本结构,但你想让他们的孩子(CO2,CH4等)使用它。但是以他们自己的方式
它什么都不做,只是提供一个公共模板,它将被它的子类共享
抽象类不能直接实例化,但必须从抽象类派生才能使用。一个类必须是抽象的,如果它包含抽象方法:或者直接
abstract class Foo {
abstract void someMethod();
}
或间接地
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
然而,一个类可以是抽象的,而不包含抽象方法。这是一种防止直接瞬化的方法,例如。
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
抽象类的后一种风格可以用来创建“类接口”类。与接口不同,抽象类允许包含非抽象方法和实例变量。您可以使用它为扩展类提供一些基本功能。
另一种常见的模式是在抽象类中实现主要功能,并在由扩展类实现的抽象方法中定义部分算法。愚蠢的例子:
abstract class Processor {
protected abstract int[] filterInput(int[] unfiltered);
public int process(int[] values) {
int[] filtered = filterInput(values);
// do something with filtered input
}
}
class EvenValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove odd numbers
}
}
class OddValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove even numbers
}
}
推荐文章
- JavaFX应用程序图标
- Java:强/软/弱/幻影引用的区别
- 在序列化和反序列化期间JSON属性的不同名称
- 获取Android设备名称
- Gradle代理配置
- 如何获得具有已知资源名称的资源id ?
- 在Android上将字符串转换为整数
- 为什么“System.out。”println“工作在Android?
- 在Java中什么时候使用可变参数?
- Mockito的argumentCaptor的例子
- 我如何告诉Spring Boot哪个主类用于可执行jar?
- 如何将Java8流的元素添加到现有的列表中
- 在Java 8中是否可以转换流?
- 不区分大小写的字符串作为HashMap键
- 什么是maven中的“pom”打包?