抽象类是无法实例化的类。通过创建可以实例化的继承子类来使用抽象类。抽象类为继承的子类做一些事情:
- 定义继承子类可以使用的方法。
- 定义继承子类必须实现的抽象方法。
- 提供一个公共接口,该接口允许子类与所有其他子类互换。
这是一个例子:
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()。
这是正确的
ImplementingClass。
public class ImplementingClass extends AbstractClass{ public void abstractMethod() { System.out.print("abstractMethod()"); }}请注意,你不必定义
implementedMethod()或f
inalMethod()。它们已经由定义
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!"); }}你不能这样做,因为
finalMethod()in的实现
AbstractClass被标记为的最终实现
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类型,它也会显示
"Overriden!"。这是因为我们实例化的对象实际上是一个
ImplementingClass,它
implementedMethod()当然会被覆盖。(你可能已经将其称为多态。)
如果我们希望访问特定于特定子类的成员,则必须首先将其转换为该子类:
// Say ImplementingClass also contains uniqueMethod()// To access it, we use a cast to tell the runtime which type the object isAbstractClass 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!"); }}你不能在接口中实现方法。这意味着,如果你实现两个不同的接口,则这些接口中的不同方法不会冲突。由于接口中的所有方法都是抽象的,因此你必须实现该方法,并且由于你的方法是继承树中的唯一实现,因此编译器知道它必须使用你的方法。



