简体   繁体   English

在两个类之间共享公共代码的最佳方式

[英]Best way to share common code between two classes

I got two classes, Player and Enemy, and both share a few standard methods that I do not want to duplicate.我有两个类,Player 和 Enemy,它们共享一些我不想重复的标准方法。 The player and Enemy class already extend an another class, so making an abstraction class won't help.玩家和敌人 class 已经扩展了另一个 class,因此抽象 class 无济于事。

Player Class:玩家Class:

public class Player extends Game {

public void getPlayer() {
        //imp
        return Player;
    }
@Override
public void getWorld() {
        return world;
    }
}

Enemy Class敌人 Class

public class Enemy extends Game {

public void getPlayer() {
        //imp
        return Player;
    }
@Override
public void getWorld() {
        return world;
    }
}

Before worrying about sharing code, you must first fix this glaring mistake: public class Player extends Game { .在担心共享代码之前,您必须首先修复这个明显的错误: public class Player extends Game { . There is no way on earth that either class above should extend from Game, none since a "Player" cannot satisfy the logical "is-a" relationship to Game.上面的class不可能从 Game 扩展,因为“Player”不能满足与 Game 的逻辑“is-a”关系。 Using other games as an analogy, should a chess piece extend a ChessGame class?以其他游戏类比,一个棋子是否应该扩展一个ChessGame class? Is a chess piece a more specialized sub-type of chess game?棋子是一种更专业的国际象棋游戏子类型吗? No. The game holds chess pieces, a "has-a" relationship exists, not an "is-a" relationship.不。游戏中包含棋子,存在“has-a”关系,而不是“is-a”关系。

Instead there is a "has-a" relationship, possibly in both directions since Game will obviously hold references to Players and Enemies, and possibly Player and Enemy might need references to the single Game instance.相反,存在“has-a”关系,可能在两个方向上,因为 Game 显然会保存对 Players 和 Enemies 的引用,并且 Player 和 Enemy 可能需要对单个 Game 实例的引用。 So, in short, the relationship should be one of composition: give the classes a Game field, if a direct relationship is needed, and feed in the Game instance via constructor parameter or setter.因此,简而言之,这种关系应该是一种组合:如果需要直接关系,则为类提供一个 Game 字段,并通过构造函数参数或 setter 提供 Game 实例。

Fixing this will get rid of your issue:解决这个问题将解决您的问题:

The player and Enemy class already extend an another class, so making an abstraction class won't help.玩家和敌人 class 已经扩展了另一个 class,因此抽象 class 无济于事。

Then I would give Player and Enemy a common abstract type to inherit from, say AbstractPlayer, and it can be either an interface or an abstract class, depending on all your requirements.然后我会给 Player 和 Enemy 一个通用的抽象类型来继承,比如 AbstractPlayer,它可以是接口或抽象 class,具体取决于您的所有要求。

If you need to use an outside Game class in your program, either use it directly, or have another class, say MyGame, inherit from Game.如果你需要在你的程序中使用外部游戏 class,要么直接使用它,要么有另一个 class,比如 MyGame,继承自 Game。

Something like:就像是:

public abstract class AbstractPlayer {
    private Game game;
    private String name;
    
    public AbstractPlayer(String name, Game game) {
        this.name = name;
        this.game = game;
    }
    
    public World getWorld() {
        // if game has this method, ... which we currently don't know
        return game.getWorld();
    }
    
    // ... other methods and fields
}

and then,然后,

public class Player extends AbstractPlayer {
    public Player(String name, Game game) {
        super(name, game);
        // .....
    }
}
public class MyGame extends Game {
    private AbstractPlayer player;
    private AbstractPlayer enemy;
    
    // ....
}

Side note, this:旁注,这个:

public void getPlayer() {
        //imp
        return Player;
    }

doesn't make sense, since you're creating a getter that returns itself, the this .没有意义,因为您正在创建一个返回自身的 getter,即this No need for this here.这里不需要这个。

Nor does this:这也不是:

public void getWorld() {
   return world;
}

since you're declaring a getter as a void method, and then returning something from it.因为您将 getter 声明为void方法,然后从中返回一些东西。

Yes, making an abstraction class will help, since Player and Enemy both extend the same class. Therefore you can create an abstraction class (eg PlayerEnemyBase) with PlayerEnemyBase extends Game which defines the shared behaviour and then have Player and Enemy extend PlayerEnemyBase.是的,进行抽象 class 会有所帮助,因为 Player 和 Enemy 都扩展了相同的 class。因此,您可以使用PlayerEnemyBase extends Game创建一个抽象 class(例如 PlayerEnemyBase),它定义了共享行为,然后让 Player 和 Enemy 扩展 PlayerEnemyBase。

However, I agree with Hovercraft that having Player extend Game seems a bit strange since inheritance in java is meant to model an Is-A relationship.但是,我同意 Hovercraft 的观点,即让 Player 扩展 Game 似乎有点奇怪,因为 inheritance in java 意味着 model 是一种 Is-A 关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在两个或多个项目之间共享公共代码(例如域类)的最佳方法是什么? - What is the best way to share common code (such as domain classes) between two or more projects? 跨类共享通用代码的最佳实践 - Best practice to share common code across classes 在多个类中共享公共属性的最佳方法是什么? - What is the best way to share common properties in multiple classes? 编写包含通用功能的两个枚举类的最佳方法是什么 - What is the best way to write two enum classes containing common functionality 在具体的JPA类之间共享Java实现的最佳方法? - Best way to share Java implementation between concrete JPA classes? 在不同的JUnit测试类之间共享数据的最佳方法是什么 - What is the best way to share data between different JUnit test classes 在两个或多个类之间共享同一接口实现的有效方法 - Efficient way to share the same interface implementation between two or more classes 在两个类之间共享代码(使用抽象操作) - Share code (which uses an abstract operation) between two classes 在具有不同基类的活动之间共享代码的最佳方式是什么? - What is the optimal way to share code between Activities with different base classes? 在两个类之间共享一个线程池 - Share a threadpool between two classes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM