Java中的抽象类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1320745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:12:54  来源:igfitidea点击:

Abstract class in Java

javaoopinterfaceabstract-class

提问by

What is an "abstract class" in Java?

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

回答by Noon Silk

It's a class that cannot be instantiated, and forces implementing classes to, possibly, implement abstract methods that it outlines.

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

回答by Daniel Rikowski

A Java class becomes abstract under the following conditions:

Java 类在以下条件下变为抽象类:

1. At least one of the methods is marked as abstract:

1. 至少一种方法被标记为抽象:

public abstract void myMethod()

In that case the compiler forces you to mark the whole class as abstract.

在这种情况下,编译器会强制您将整个类标记为抽象类。

2. The class is marked as abstract:

2.类被标记为抽象:

abstract class MyClass

As already said: If you have an abstract method the compiler forces you to mark the whole class as abstract. But even if you don't have any abstract method you can still mark the class as abstract.

如前所述:如果您有一个抽象方法,编译器会强制您将整个类标记为抽象。但即使您没有任何抽象方法,您仍然可以将类标记为抽象。

Common use:

常见用途:

A common use of abstract classes is to provide an outline of a class similar like an interface does. But unlike an interface it can already provide functionality, i.e. some parts of the class are implemented and some parts are just outlined with a method declaration. ("abstract")

抽象类的一个常见用途是像接口一样提供类的概要。但与接口不同的是,它已经可以提供功能,即类的某些部分已实现,而某些部分仅用方法声明进行概述。(“抽象的”)

An abstract class cannot be instantiated, but you can create a concrete class based on an abstract class, which then can be instantiated. To do so you have to inherit from the abstract class and override the abstract methods, i.e. implement them.

抽象类不能被实例化,但是你可以基于抽象类创建一个具体的类,然后可以实例化。为此,您必须从抽象类继承并覆盖抽象方法,即实现它们。

回答by Juri

Simply speaking, you can think of an abstract class as like an Interface with a bit more capabilities.

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

You cannot instantiate an Interface, which also holds for an abstract class.

您不能实例化接口,它也适用于抽象类。

On your interface you can just define the method headers and ALL of the implementers are forcedto implement allof 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 classper 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();
}

Otherwise for normal methods of an abstract class, the "inheriters" can either just use the default behavior or override it, as usual.

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

Example:

例子:

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();
}

回答by Ashvin Ranpariya

Solution - base class (abstract)

解决方案——基类(抽象)

public abstract class Place {

String Name;
String Postcode;
String County;
String Area;

Place () {

        }

public static Place make(String Incoming) {
        if (Incoming.length() < 61) return (null);

        String Name = (Incoming.substring(4,26)).trim();
        String County = (Incoming.substring(27,48)).trim();
        String Postcode = (Incoming.substring(48,61)).trim();
        String Area = (Incoming.substring(61)).trim();

        Place created;
        if (Name.equalsIgnoreCase(Area)) {
                created = new Area(Area,County,Postcode);
        } else {
                created = new District(Name,County,Postcode,Area);
        }
        return (created);
        }

public String getName() {
        return (Name);
        }

public String getPostcode() {
        return (Postcode);
        }

public String getCounty() {
        return (County);
        }

public abstract String getArea();

}

回答by adatapost

Little addition to all these posts.

对所有这些帖子的补充很少。

Sometimes you may want to declare a class and yet not know how to define all of the methods that belong to that class. For example, you may want to declare a class called Writerand include in it a member method called write(). However, you don't know how to code write()because it is different for each type of Writer devices. Of course, you plan to handle this by deriving subclass of Writer, such as Printer, Disk, Network and Console.

有时您可能想声明一个类,但不知道如何定义属于该类的所有方法。例如,您可能想要声明一个名为Writer的类,并在其中包含一个名为write()的成员方法 。但是,您不知道如何编写write()代码,因为每种类型的 Writer 设备都不同。当然,您计划通过派生 Writer 的子类来处理此问题,例如打印机、磁盘、网络和控制台。

回答by janko

An abstract class can not be directly instantiated, but must be derived from to be usable. A class MUSTbe abstract if it contains abstract methods: either directly

抽象类不能直接实例化,但必须从其派生才能使用。一个类必须是抽象的,如果它包含抽象方法:要么直接

abstract class Foo {
    abstract void someMethod();
}

or indirectly

或间接

interface IFoo {
    void someMethod();
}

abstract class Foo2 implements IFoo {
}

However, a class can be abstract without containing abstract methods. Its a way to prevent direct instantation, e.g.

然而,一个类可以是抽象的而不包含抽象方法。它是一种防止直接实例化的方法,例如

abstract class Foo3 {
}

class Bar extends Foo3 {

}

Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!

The latter style of abstract classes may be used to create "interface-like" classes. Unlike interfaces an abstract class is allowed to contain non-abstract methods and instance variables. You can use this to provide some base functionality to extending classes.

后一种抽象类风格可用于创建“类接口”类。与接口不同,抽象类允许包含非抽象方法和实例变量。您可以使用它来为扩展类提供一些基本功能。

Another frequent pattern is to implement the main functionality in the abstract class and define part of the algorithm in an abstract method to be implemented by an extending class. Stupid example:

另一种常见的模式是在抽象类中实现主要功能,并在一个抽象方法中定义部分算法,由扩展类实现。愚蠢的例子:

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
    }
}

回答by Imagist

An abstract class is a class which cannot be instantiated. An abstract class is used by creating an inheriting subclass that canbe instantiated. An abstract class does a few things for the inheriting subclass:

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

  1. Define methods which can be used by the inheriting subclass.
  2. Define abstract methods which the inheriting subclass must implement.
  3. Provide a common interface which allows the subclass to be interchanged with all other subclasses.
  1. 定义继承子类可以使用的方法。
  2. 定义继承子类必须实现的抽象方法。
  3. 提供一个公共接口,允许子类与所有其他子类互换。

Here's an example:

下面是一个例子:

abstract public class AbstractClass
{
    abstract public void abstractMethod();
    public void implementedMethod() { System.out.print("implementedMethod()"); }
    final public void finalMethod() { System.out.print("finalMethod()"); }
}

Notice that "abstractMethod()" doesn't have any method body. Because of this, you can't do the following:

请注意,“abstractMethod()”没有任何方法体。因此,您不能执行以下操作:

public class ImplementingClass extends AbstractClass
{
    // ERROR!
}

There's no method that implements abstractMethod()! So there's no way for the JVM to know what it's supposed to do when it gets something like new ImplementingClass().abstractMethod().

没有实现的方法abstractMethod()!因此,当 JVM 获得类似new ImplementingClass().abstractMethod().

Here's a correct ImplementingClass.

这是一个正确的ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
}

Notice that you don't have to define implementedMethod()or finalMethod(). They were already defined by AbstractClass.

请注意,您不必定义implementedMethod()finalMethod()。它们已经由 定义AbstractClass

Here's another correct ImplementingClass.

这是另一个正确的ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

In this case, you have overridden implementedMethod().

在这种情况下,您已覆盖implementedMethod().

However, because of the finalkeyword, the following is not possible.

但是,由于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!"); }
}

You can't do this because the implementation of finalMethod()in AbstractClassis marked as the final implementation of finalMethod(): no other implementations will be allowed, ever.

您不能这样做,因为finalMethod()in的实现AbstractClass被标记为 的最终实现finalMethod():永远不允许其他实现。

Now you can alsoimplement an abstract class twice:

现在你还可以实现一个抽象类两次:

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

Now somewhere you could write another method.

现在你可以在某处编写另一种方法。

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()"
}

Notice that even though we declared ban AbstractClasstype, it displays "Overriden!". This is because the object we instantiated was actually an ImplementingClass, whose implementedMethod()is of course overridden. (You may have seen this referred to as polymorphism.)

请注意,即使我们声明b了一个AbstractClass类型,它也会显示"Overriden!". 这是因为我们实例化的对象实际上是 an ImplementingClass,它implementedMethod()当然被覆盖了。(您可能已经看到这称为多态性。)

If we wish to access a member specific to a particular subclass, we must cast down to that subclass first:

如果我们希望访问特定于特定子类的成员,我们必须首先转换为该子类:

// 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();

Lastly, you cannot do the following:

最后,您不能执行以下操作:

public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
    ... // implementation
}

Only one class can be extended at a time. If you need to extend multiple classes, they have to be interfaces. You can do this:

一次只能延长一门课。如果您需要扩展多个类,它们必须是接口。你可以这样做:

public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
    ... // implementation
}

Here's an example interface:

这是一个示例界面:

interface InterfaceA
{
    void interfaceMethod();
}

This is basically the same as:

这与以下内容基本相同:

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

The only difference is that the second way doesn't let the compiler know that it's actually an interface. This can be useful if you want people to only implement your interface and no others. However, as a general beginner rule of thumb, if your abstract class only has abstract methods, you should probably make it an interface.

唯一的区别是第二种方式不会让编译器知道它实际上是一个接口。如果您希望人们只实现您的界面而不实现其他界面,这会很有用。但是,作为一般初学者的经验法则,如果您的抽象类只有抽象方法,您可能应该将其设为接口。

The following is illegal:

以下是非法的:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

You cannot implement methods in an interface. This means that if you implement two different interfaces, the different methods in those interfaces can't collide. Since all the methods in an interface are abstract, you have to implement the method, and since your method is the only implementation in the inheritance tree, the compiler knows that it has to use your method.

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

回答by Andreas Dolk

Get your answers here:

在此处获取您的答案:

Abstract class vs Interface in Java

Java中的抽象类与接口

Can an abstract class have a final method?

抽象类可以有 final 方法吗?

BTW - those are question you asked recently. Think about a new question to build up reputation...

BTW - 这些是你最近问的问题。想一个新问题来建立声誉......

Edit:

编辑:

Just realized, that the posters of this and the referenced questions have the same or at least similiar name but the user-id is always different. So either, there's a technical problem, that keyur has problems logging in again and finding the answers to his questions or this is a sort of game to entertain the SO community ;)

刚刚意识到,此问题的发布者和引用的问题具有相同或至少相似的名称,但用户 ID 始终不同。因此,要么存在技术问题,要么keyur 无法再次登录并找到问题的答案,要么这是一种娱乐SO 社区的游戏;)

回答by Andreas Dolk

Class which can have both concrete and non-concrete methods i.e. with and without body.

可以有具体和非具体方法的类,即有和没有身体。

  1. Methods without implementation must contain 'abstract' keyword.
  2. Abstract class can't be instantiated.
  1. 没有实现的方法必须包含 'abstract' 关键字。
  2. 抽象类不能被实例化。

回答by Ketan G

An abstract class is a class that is declared abstract — it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.

抽象类是声明为抽象的类——它可能包含也可能不包含抽象方法。抽象类不能被实例化,但它们可以被子类化。

In other words, a class that is declared with abstract keyword, is known as abstract class in java. It can have abstract(method without body) and non-abstract methods (method with body).

换句话说,用abstract关键字声明的类,在java中称为抽象类。它可以有抽象(没有主体的方法)和非抽象方法(有主体的方法)。

Important Note:-Abstract classes cannot be used to instantiate objects, they can be used to create object references, because Java's approach to run-time Polymorphism is implemented through the use of superclass references. Thus, it must be possible to create a reference to an abstract class so that it can be used to point to a subclass object. You will see this feature in the below example

重要说明:-抽象类不能用于实例化对象,它们可以用于创建对象引用,因为 Java 的运行时多态方法是通过使用超类引用来实现的。因此,必须可以创建对抽象类的引用,以便它可以用于指向子类对象。您将在下面的示例中看到此功能

abstract class Bike{  
  abstract void run();  
}  

class Honda4 extends Bike{  
    void run(){
        System.out.println("running safely..");
    }  

    public static void main(String args[]){  
       Bike obj = new Honda4();  
       obj.run();  
    }  
}