这些方法在Java中访问其他类有什么区别?

时间:2018-06-06 00:23:10

标签: java minecraft bukkit

目前我正在进入Java开发阶段,我正在努力理解实例和事物的概念。当我有一个变量或方法,我需要在另一个类中访问,目前我做

public class Class1 implements Listener {
private final Main main;
private final Class2 class2;

public Class1(Main main, Class2 class2) {
    this.main= main;
    this.class2 = class2;
}

我应该提一下,我正在尝试开发一个Minecraft插件,因此Listener类必须实现Listener。但是,当我尝试为需要引用2个类的类注册事件(再次,对于我的世界来说,另一件事)时,代码变得混乱。例如,要获取引用其他2个类的类的类,eventRegister可以如下所示:(在主类中)

  pm.registerEvents(new ClassX(this, new ClassY(this, new ClassZ(this))), this);

(注册事件需要一个监听器和一个主类)

我的问题是:这种获取另一个类的方法与简单扩展它之间有什么区别。它有区别吗?

5 个答案:

答案 0 :(得分:2)

扩展课程时,您正在应用继承。您可以访问超类中的所有public方法。

实施界面时,您需要签署一份合同,您必须从该界面实施所有非默认方法。

答案 1 :(得分:1)

当你将一个实例传递给另一个实例时(通过你的情况下的构造函数),你正在应用object composition,这类似于说“我会将这个特定的引擎放入这个特定的汽车”。您可能希望将不同的引擎放入不同的汽车中,因此您将传递不同的引擎作为构造函数。

implements被称为inheritance。继承背后的想法是知道所有类都是的同类。例如,您可能会说“所有汽车都可以转左()和转弯()”,因此,如果有人想要自己制造汽车(或者在您的情况下 - 他们自己的插件),他们的汽车也需要能够{{1 }和turnRight()

让我们回到你的问题。如果您看到一段看起来“通用”的代码,您可能希望将通用部分提取到自己的类中,然后继承该类。例如,“所有动物都可以turnLeft()”或“所有工具都可以shout() - d”。但是,如果你想要这只鸭子知道那只鸭子 - 你需要在另一只鸭子中引用一只鸭子。

但是,这并不意味着您需要使用构造函数。构造函数用于引用该对象不能存在(不能处于有效状态)。例如,use()有意义,但new Duck(new DuckBrain())没有意义。对于这些情况,您可以引入setters(在链接中搜索Java示例)。 Setter是改变对象包含内容的方法。

答案 2 :(得分:1)

不要给类提供所需的每个事物的实例,而是给它存储它们的对象。在你的情况下,它可能是你的插件的主要类。

class ClassA implements Listener {

    private final MyPlugin plugin;

    public ClassA(MyPlugin plugin) {
        this.plugin = plugin;
    }
}

请确保使用访问修饰符或getter从MyPlugin访问ClassA中的所有内容。

答案 3 :(得分:0)

你一直在做什么是完全正常的,并且受到鼓励。过度使用未明确设计的继承会导致错误的代码。

您也通过构造函数传递每个类所需的内容,这也是称为依赖注入的良好实践,并且有助于更好地进行测试以及编写单元测试。

对于高级项目,使用依赖注入框架以管理传递到许多类的依赖项是很常见的,但对于小插件来说它不是必需的。

根据这些类的可重用性,您可能希望为它们创建一些接口。

如果使用依赖注入构建类成为一件苦差事,您可以查看几种模式来提供帮助。

工厂和构建器模式在整个行业中得到广泛使用,具体取决于构建对象的频率,复杂程度和变化程度。

创建的复杂对象通常很适合Factory pattern

具有高度可变性的简单对象非常适合builder pattern

如果通过构造函数传递所有内容变得困难,您可以在构造之后始终初始化对象,但这会产生维护成本,因为您需要确保正确初始化对象。

答案 4 :(得分:-1)

为什么你的class1需要引用class2?它是OO编程中的一个对象还是一个东西,这意味着你的代码会变得非常偶然,这是一个糟糕的设计,你应该使用其他设计模式来解耦你的代码,即Class1不应该依赖于Class2。

回到你的问题通过构造函数传递对象与扩展它的区别是什么?

当你扩展一个类时,你可以覆盖母类中的一些方法,即Dog extends Animal,或者你甚至可以在超类中调用该方法(通过super.method()来调用Animal类)。

当你在这种情况下通过构造函数传递一个对象时,你可以使用你通过构造函数传入的对象。

使代码更简洁的最好方法我建议监听器模式(pub子)有现有的库,例如https://github.com/greenrobot/EventBus,你可以在其中创建一个事件,例如当玩家去世时你可以创建一个事件另一个订阅该事件的类,当事件发生时,它将通知所有订阅者触发一个函数。现在您不需要将所有类组合在一起。