Java中的“抽象类”是什么?


当前回答

在这里找到你的答案:

Java中的抽象类与接口

抽象类可以有final方法吗?

顺便说一句,这是你最近问的问题。思考一个建立声誉的新问题……

编辑:

刚刚意识到,这个和参考问题的海报有相同或至少相似的名称,但用户id总是不同的。所以,要么,有一个技术问题,键盘有问题再次登录,并找到他的问题的答案,或者这是一种娱乐So社区的游戏;)

其他回答

除了这些帖子之外。

有时你可能想声明一个 类,但不知道如何定义 所有的方法都属于这个 类。例如,你可能想要 声明一个名为Writer和的类 在它中包含一个名为 写()。但是,您不知道如何编写write()代码,因为它就是 每种类型的作者都不一样 设备。当然,你打算处理 通过派生Writer的子类, 如打印机,磁盘,网络和 控制台。

在这里找到你的答案:

Java中的抽象类与接口

抽象类可以有final方法吗?

顺便说一句,这是你最近问的问题。思考一个建立声誉的新问题……

编辑:

刚刚意识到,这个和参考问题的海报有相同或至少相似的名称,但用户id总是不同的。所以,要么,有一个技术问题,键盘有问题再次登录,并找到他的问题的答案,或者这是一种娱乐So社区的游戏;)

它是一个不能被实例化的类,并且强制实现类尽可能地实现它概述的抽象方法。

简单地说,您可以将抽象类看作是具有更多功能的接口。

你不能实例化一个接口,这也适用于一个抽象类。

On your interface you can just define the method headers and ALL of the implementers are forced to implement all of them. On an abstract class you can also define your method headers but here - to the difference of the interface - you can also define the body (usually a default implementation) of the method. Moreover when other classes extend (note, not implement and therefore you can also have just one abstract class per child class) your abstract class, they are not forced to implement all of your methods of your abstract class, unless you specified an abstract method (in such case it works like for interfaces, you cannot define the method body).

public abstract class MyAbstractClass{
  public abstract void DoSomething();
}

否则,对于抽象类的普通方法,“继承者”可以像往常一样只使用默认行为或重写它。

例子:

public abstract class MyAbstractClass{

  public int CalculateCost(int amount){
     //do some default calculations
     //this can be overriden by subclasses if needed
  }

  //this MUST be implemented by subclasses
  public abstract void DoSomething();
}

抽象类是不能被实例化的类。抽象类是通过创建可实例化的继承子类来使用的。抽象类为继承的子类做了一些事情:

定义可由继承子类使用的方法。 定义继承子类必须实现的抽象方法。 提供一个公共接口,允许子类与所有其他子类交换。

这里有一个例子:

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!"); }
}

不能在接口中实现方法。这意味着如果实现两个不同的接口,这些接口中的不同方法不能冲突。由于接口中的所有方法都是抽象的,因此必须实现该方法,并且由于您的方法是继承树中唯一的实现,因此编译器知道它必须使用您的方法。