When to use abstract class as type

ⅰ亾dé卋堺 提交于 2021-02-05 06:56:05

问题


So while trying to understand abstract classes, there is still one thing I am confused on. When do you ever want to declare an object type of its abstract class. For example

public abstract class GameObject
{
 public abstract void draw();
 public static void main(String[] args)
 {
 GameObject player = new Player();
 Menu menu = new Menu();
 }

}
public class Player extends GameObject
{
 override 
 public void draw()
 {
 // Something
 }

}
public class Menu extends GameObject
{
 override 
 public void draw()
 {
 // Something
 }
}

Normally, I would just instaniate a player object of player type. However, I have seen abstract classes used as the variable type of the new object. When would you ever choose to do this? Thanks!


回答1:


You would do that every time you need the variable to be an instance of the abstract class, but don't really care about what the concrete type is (and don't want the rest of the code to assume a specific subclass is used). For example:

GameObject[] gameObjects = new GameObject[] {new Menu(), new Player()};
drawAll(gameObjects);

...

private void drawAll(GameObject[] gameObjects) {
    for (GameObject gameObject : gameObjects) {
        gameObject.draw();
    }
}

The abstract type is often used as a return type (because you don't want the caller to know what concrete type is returned: it could change later, or could vary based on the arguments of the configuration).

It's also often used as method parameter type, so that the method can accept an argument of any subclass of the abstract type and use it polymorphically.

And of course, as an array/collection type, to be able to store instances of multiple subclasses in a unique collection.




回答2:


Say you want to add functionality to make a particular GameObject invisible. A raw implementation would look like:

void makeInvisible(GameObject object) { ... }

This method is supposed to work with any kind of GameObject (and is able to make them all invisible -- or it can throw an IllegalArgumentException if the "wrong" kind of object is passed).

Your question however seems to be particularly concerned with this kind of declaration:

GameObject gameObject = new Player(); // why on earth would you do this -- you wonder

First think of how often you've seen the following:

List<String> stringList = new ArrayList<>();

And yet, this is recommended as best practice because the rest of the code should not be aware of the particular List implementation chosen. You can change that to a LinkedList later on without changing anything but that line above.

If you can find no reasonable scenario where such a declaration would make sense for your abstraction, it is probably a symptom for one of the following:

  • You're not willing to make use of polymorphism: that is, you want to define the specific logic for each subtype and never deal with them "generically" -- like in the makeInvisible example above
  • Your abstraction isn't buying you much; in other words, it is not usable as such and you should probably re-consider your design.

In your particular case, that abstract class is not particularly well-designed.

First of all, it makes the main() method visible to all its subclasses and there's no reason why you would want to have main in scope for Player or Menu.

Secondly, it would suit better as an interface (Drawable, maybe), since all it does is define the signature for the draw method. This change would make its polymorphic capabilities more obvious, as you should be able to spot where you need to treat objects as mere Drawables and this should answer your question.




回答3:


Let's say you have an abstract Animal class, with methods such as eat(), sound(), etc.

You can create classes that extend this Animal class, let's say Dog and Cat.

If there are abstract methods in the abstract class (which isn't mandatory), you'll need to implement that method in each type that extends Animal.

If the method is not abstract, you can still override it if you want it to do something different from the main class.

If you still don't fully understand try this video https://www.youtube.com/watch?v=TyPNvt6Zg8c.



来源:https://stackoverflow.com/questions/33457393/when-to-use-abstract-class-as-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!