java中的抽象类

发布于 2024-08-15 18:01:04 字数 23 浏览 8 评论 0原文

可以在Java中创建抽象类的对象

Is possible to create objects of an abstract class in Java

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

〆一缕阳光ご 2024-08-22 18:01:04

如果你有一个像这样的抽象类:

public abstract class Foo
{
     public void bar()
     {
         car();
     }

     protected abstract void car();
}

如果你能够做到这一点:

final Foo foo;

foo = new Foo();
foo.bar();

假设“car”方法没有与之关联的代码,那么当“bar”方法调用“car”方法时会发生什么?

但是,您可以这样做:

class Star 
    extends Bar
{
    protected void car()  
    {
    }
}

然后执行:

final Foo foo;

foo = new Star();
foo.bar();

这次您有一个 Foo 类型的变量,它可以保存 Foo 的任何具体子类(非抽象的类是具体的)。现在,当您调用“bar”方法时,它使用 Foo 中的方法,而当调用“car”方法时,它使用 Star 中的方法。这是多态性的一个例子。

If you had an abstract class like this:

public abstract class Foo
{
     public void bar()
     {
         car();
     }

     protected abstract void car();
}

if you were able to do this:

final Foo foo;

foo = new Foo();
foo.bar();

what would happen when the "bar" method called the "car" method given that the "car" method has no code associated with it?

You can do this however:

class Star 
    extends Bar
{
    protected void car()  
    {
    }
}

and then do:

final Foo foo;

foo = new Star();
foo.bar();

This time you have a variable of type Foo that can hold any concrete subclass of Foo (a class that is not abstract is concrete). Now when you call the "bar" method it uses the one in Foo, and when the "car" method is called it uses the one in Star. That is an example of polymorphism.

メ斷腸人バ 2024-08-22 18:01:04

尝试实例化抽象类将在编译时失败,除非您提供其所有抽象方法的实现(通过实现匿名内部类):

Runnable r = new Runnable() {
    public void run() {
        //do something
    }
};

An attempt to instantiate an abstract class will fail at compile time unless you provide the implementation of all its abstract methods (by implementing an anonymous inner class):

Runnable r = new Runnable() {
    public void run() {
        //do something
    }
};
你的心境我的脸 2024-08-22 18:01:04

假设这是一个完全新手的问题,那么 Java 中的抽象类如下:

Java 中的类主要有三种类型:接口抽象类类。其中每一个都添加了一些特定于实际类定义的内容;

  • 接口定义了可以在类中找到(并且必须实现)的方法。简而言之,接口定义行为。
  • 抽象类实现一些功能,并在此之上定义附加的抽象方法,这些方法必须由扩展类实现。使用抽象类与直接类继承类似。
  • 只是您很可能已经熟悉的类。

使用任何可能的类类型都有很多理由,但是在现代 Java 代码中最常见的是,您会看到很多接口和一堆实现这些接口的类。

示例:类

考虑以下类:

public class Cat {
 public void speak() {
  System.out.println("Meow!");
 }
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!"); 
 }
}

这是一个非常简单的类,是每个 Java 编码人员(甚至初学者)都熟悉的类型。这里没什么特别的。然而,这样你就会遇到一个问题:如果你有一只基本相同的狗,但它明显是在吠叫而不是喵喵叫,该怎么办?

示例:抽象类

CatDog”问题可以通过继承来解决。传统的标准继承看起来像这样:

public class Animal {
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
 }
}

public class Cat extends Animal {
 public void speak() {
  System.out.println("Meow!");
 }
}

public class Dog extends Animal {
 public void speak() {
  System.out.println("Bark! Bark!");
 }
}

然而这里存在一个问题:要真正发出 Cat 喵喵声或 Dog 吠声,您必须有代码来检查到底是哪种动物动物是,将其转换为正确的类型,然后调用该方法:

if (animal instanceof Dog) {
 ((Dog) animal).speak();
} else if (animal instanceof Cat) {
 ((Cat) animal).speak();
}

如您所见,这种代码完全没有意义!我们当然希望能够直接调用 animal.speak(),对吧?为此,我们有抽象类!通过用此替换上面示例中的 Animal 类,

public abstract class Animal {
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
 }
 public abstract void speak();
}

您只需调用 animal.speak 即可让您的 Dog 吠叫和 Cat 喵叫()!太棒了,不是吗?

请注意,您还可以将 speak() 的默认行为定义为 Animal,然后在 CatDog< 中重写该方法。 /code> 有时,这甚至比我刚才在这里展示的更有意义。

不管怎样,另一个问题出现了:如果你的既是动物又是宠物怎么办? Java 只允许单继承以避免钻石继承问题,所以你不能只拥有另一个超类对于他们来说。您可以将其添加为 Animal 的超类,但话又说回来,并非所有动物都是宠物 - 我的院子池塘里肯定没有河马!

示例:接口

由于接口仅定义行为,而不是实际实现它们(这实际上是相关的关键字!)您可以使用接口来定义原始类的附加行为。让我们假设宠物通常可以进行美容等,因此 Pet 的界面如下所示:

public interface Pet {
 void groom(Brush b);
}

现在只需将 implements Pet 添加到您的 Dog > 现在可以修饰了!只是为了确保,您的 Dog 类的第一行应如下所示:

public class Dog extends Animal implements Pet {

Now to groom your Dog or any other Pet you can do这:

if (animal instanceof Pet) ((Pet) animal).groom();

差不多就是这样了。作为练习,尝试将 Animal 实现为接口;请注意,接口实际上可以扩展其他接口。

附言。枚举和匿名内部类也可以被视为类类型,但是它们并不是每个人在学习 Java 基础知识后应该立即了解的主要类型。

Assuming this is a complete newbie question, here's what abstract classes are in Java:

There's three main types of classes in java, interfaces, abstract classes and classes. Each of these adds something specific to the actual class definition;

  • Interface defines the methods one can find (and must implement) in a class. In short, interfaces define behaviour.
  • Abstract classes implement some functionality and on top of that define additional abstract methods which must be implemented by the classes extending. Using abstract classes is similar to direct class inheritance.
  • Classes are just, well, classes which you most likely are already familiar with.

There's plenty of reasons for using any of the possible class types, however most commonly in modern Java code you will see a lot of interfaces and a bunch of classes implementing those interfaces.

Examples: Class

Consider the following class:

public class Cat {
 public void speak() {
  System.out.println("Meow!");
 }
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!"); 
 }
}

This is a very simple class and the kind every Java coder, even the beginners, are familiar with. Nothing special here. However with this you have an issue: what if you have a Dog that's basically the same but it obviously barks instead of meows?

Example: Abstract class

The "Cat or Dog" problem can be solved with inheritance. Traditionally standard inheritance looks like this:

public class Animal {
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
 }
}

public class Cat extends Animal {
 public void speak() {
  System.out.println("Meow!");
 }
}

public class Dog extends Animal {
 public void speak() {
  System.out.println("Bark! Bark!");
 }
}

However herein lies a problem: To actually make the Cat meow or the Dog bark, you have to have code which checks what kind of animal exactly the animal is, cast it to correct type and then call the method:

if (animal instanceof Dog) {
 ((Dog) animal).speak();
} else if (animal instanceof Cat) {
 ((Cat) animal).speak();
}

As you can see, this sort of code is completely pointless! Surely we would like to just be able to call animal.speak() directly, right? And for that purpose, we have abstract classes! By replacing the Animal class in the example above with this

public abstract class Animal {
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
 }
 public abstract void speak();
}

you can make your Dog bark and Cat meow just by calling animal.speak()! Great, isn't it?

Note that you could also define the default behaviour of speak() to Animal and then just override that method in Cat and Dog and sometimes that even does make sense more than what I just showed here.

Anyway, another problem arises: What if your Dog is an Animal and also a Pet? Java only allows for single inheritance to avoid diamond inheritance problem so you can't just have another superclass for them. You could add it as a superclass for Animal but then again, not all animals are pets - there certainly isn't a hippo in my yard pond!

Example: Interface

Since interfaces only define behaviour instead of actually implement them (and that's actually the related keyword!) you can use interfaces to define additional behaviour to your original class. Lets assume that pets generally can be groomed among other things, so the interface for Pet would be like this:

public interface Pet {
 void groom(Brush b);
}

Now just add implements Pet to your Dog and it's now groomable! Just to make sure, the first line of your Dog class should look like this:

public class Dog extends Animal implements Pet {

Now to groom your Dog or any other Pet you can do this:

if (animal instanceof Pet) ((Pet) animal).groom();

That's pretty much it. As an exercise, try implementing Animal as an interface; do note that interfaces can actually extend other interfaces.

PS. Also enums and anonymous inner classes can be considered as class types, however they're not quite the main ones everyone should know right after learning the basics of Java.

生生漫 2024-08-22 18:01:04

如果您的意思是这样的话,您不能实例化抽象类(在其上调用 new )。

可以有子类的实例。这些对象也是抽象类的实例,这意味着您可以将它们强制转换为抽象类。

You cannot instantiate an abstract class (calling new on it), if that is what you mean.

It is possible to have instances of subclasses. Those objects are also instanceof the abstract class, meaning that you can cast them to it.

↘人皮目录ツ 2024-08-22 18:01:04

这取决于你的意思。

如果你的意思是:“我可以有一个抽象类的实例吗”——当然; (抽象类的)具体子类的任何实例也隐式地是抽象超类型的实例。

如果您的意思是:“我可以拥有一个抽象类的实例而不定义具体的子类型吗”——是的,如果某个库(例如 javassist、cglib)为您生成了一个具体的子类型。

如果您的意思是“以下表达式是否会通过”:

assert Modifier.isAbstract(x.getClass().getModifiers());

答案是否定的。

It depends on what you mean.

If you mean: "can I have an instance of an abstract class" -- sure; any instance of a concrete subclass (of an abstract class) implicitly is an instance of the abstract super type too.

If you mean: "can I have an instance of an abstract class without defining a concrete subtype" -- yes, if some library (for example javassist, cglib) generates a concrete subtype for you.

If you mean "will the following expression ever pass":

assert Modifier.isAbstract(x.getClass().getModifiers());

the answer is no.

清晨说晚安 2024-08-22 18:01:04

看看吧。它干净整洁javacanal.blogspot.com/

have a look on it. its clean and decent javacanal.blogspot.com/

日记撕了你也走了 2024-08-22 18:01:04

不,这是不可能的。您需要创建一个扩展抽象类的类,然后您可以创建子类的对象。

请查找示例:

abstract class AbstractClass{

    public abstract String abstractMethod(String param1,String param2);

    public void nonAbstractMethod(String param){
        System.out.println("Value of param is "+param);
    }
}

class NonAbstractClass extends AbstractClass{
    public String abstractMethod(String param1,String param2){
        String param = param1 + param2;
        return param;
    }
}


public class DemoClass{

    public static void main(String[] args) {
        NonAbstractClass nonAbstractClass = new NonAbstractClass();
        nonAbstractClass.abstractMethod("param1", "param2");
        nonAbstractClass.nonAbstractMethod("param1");
    }
}

No. Its not possible. You need to create a class which extends the abstract class, and then you can create an object of the subclass.

Please find the example:

abstract class AbstractClass{

    public abstract String abstractMethod(String param1,String param2);

    public void nonAbstractMethod(String param){
        System.out.println("Value of param is "+param);
    }
}

class NonAbstractClass extends AbstractClass{
    public String abstractMethod(String param1,String param2){
        String param = param1 + param2;
        return param;
    }
}


public class DemoClass{

    public static void main(String[] args) {
        NonAbstractClass nonAbstractClass = new NonAbstractClass();
        nonAbstractClass.abstractMethod("param1", "param2");
        nonAbstractClass.nonAbstractMethod("param1");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文