了解Java中对象的范围。还有更好的方法吗?

时间:2018-01-21 17:06:08

标签: java class oop

我想我错过了一些东西。我想从一个不同类的对象中的语句中调用一个对象中的方法,但如果我这样做,编译器会告诉我它找不到符号。

public class Test1
{
    public static void main (String[] args)
    {
        Second secondObj1 = new Second();
        Third thirdObj1= new Third();
        thirdObj1.accessMethodinSecondObj1();
    }
}

class Second
{
    int m1;

    Second()
    {
        m1 = 0;
    }

    public void methodinSecond()
    {
        System.out.println(m1);
    }
}

class Third
{
    void accessMethodinSecondObj1()
    {
        secondObj1.methodinSecond();
    }
}

所以我要做的是从secondObj1.methodinSecond()运行方法thirdObj1.accessMethodinSecondObj1()。显然,这个例子有点傻但它与一个真正的问题有关 - 但我觉得完整的代码太混乱了。

我可以通过更改签名等将secondObj1的对象引用传递给thirdObj1来解决问题,但这看起来很复杂。也许有更好的方法?

在我看来,因为我在secondObj1方法中声明了main,所以对象本身只在main范围内可见?是否没有办法让第二和第三对象进入"对话"直接相互意味着互相称呼的方法?

4 个答案:

答案 0 :(得分:0)

secondObj1main方法的局部变量。局部变量仅在声明它的块中可见。所以它只在main方法中可见。不在accessMethodinSecondObj1的方法Third内。

如果希望此方法访问`secondObj1引用的对象,则需要将该对象作为参数传递给方法:

主要:

thirdObj1.accessMethodinSecondObj1(secondObj1);

第三名:

void accessMethodinSecondObj1(Second s) {
    s.methodinSecond();
}

就像打印m1的值一样,您将m1作为参数传递给println()的方法System.out

答案 1 :(得分:0)

编译器消息是关于范围的,是的。

但是你的代码中存在更多的基础缺陷。你有什么另一个第二个对象,你想在那个方法中调用一个方法?你的第三类对象期望任何第二类对象被命名为'secondObj1'。

您已经指明了一个解决方案,更改了te签名,以便可以传递您要访问的第二类对象:

 void accessMethodinSecondObj(Second secondObj)
 {
    secondObj.methodinSecond();
 }

然后:

  thirdObj1.accessMethodinSecondObj(secondObj1);

答案 2 :(得分:0)

你是沿着正确的路线前进的。您是正确的secondObj1的范围仅限于创建它的main方法。那么我们如何将secondObj1传递给thirdObj1,因为它们并非全局可用?

首先要注意的是这些对象有关系。我们的班级ThirdSecond上有依赖。如果没有Third的实例,则accessMethodinSecondObj1()无法在Second中履行职责。在这种情况下,我们有几个选择。

最简单的方法是在需要的地方注入依赖项。在这种情况下,进入accessMethodinSecondObj1()方法:

public class Third
{
    public void accessMethodinSecondObj1(Second secondObj1)
    {
        secondObj1.methodinSecond();
    }
}

要从main拨打此电话,只需:

public class Test1
{
    public static void main (String[] args)
    {
        Second secondObj1 = new Second();
        Third thirdObj1 = new Third();
        thirdObj1.accessMethodinSecondObj1(secondObj1);
    }
}

您可以继承Second以访问其成员和方法,并使用thirdObject1.accessMethodinSecondObj1()super.methodinSecond()内进行调用。但是,当我们在这里处理抽象时,这是一个难以解决的建议,因为它可能在您的域中没有语义意义。

在这种情况下,另一个选项是composition。我们通过构造函数将Second的实例注入Third,然后Third的实例拥有该Second的实例。通过这样做,我们确保Third在调用此方法时具有Second的实例(取决于它)。这也允许在我们在Second中使用它之前对传递的accessMethodinSecondObj1()实例执行验证操作。

public class Third
{
    private Second secondObj1; 

    public Third(Second secondObj1)
    {
        this.secondObj1 = secondObj1;
    }

    public void accessMethodinSecondObj1()
    {
        this.secondObj1.methodinSecond();
    }
}

在这种情况下,我们会在main内执行以下操作:

public class Test1
{
    public static void main (String[] args)
    {
        Second secondObj1 = new Second();
        Third thirdObj1 = new Third(secondObj1);

        thirdObj1.accessMethodinSecondObj1();
    }
}

答案 3 :(得分:-1)

我们可以看到

public void methodinSecond()
{
    System.out.println(m1);
}

不是静态的,因此在

secondObj1.methodinSecond();

如果是non-static

,则无法在不创建对象的情况下调用方法

在你的主要方法

Second secondObj = new Second();

变量的范围只在块内部,所以如果你想在class Third的方法中使用它,那么将它作为参数传递给方法

 thirdObj1.accessMethodinSecondObj1(secondObj);

并将方法更改为

void accessMethodinSecondObj1(Second secondObj)
{
    secondObj.methodinSecond();
}
相关问题