Java 简单的继承但容易混淆

Java 简单的继承但容易混淆,java,Java,这是JavaTest类 package testing.test; public class JavaTest { int i=2; } package testing.test; class JavaTest2 extends JavaTest { public static void main(String[] args) { new JavaTest2().add(5); } void add(int i) {

这是JavaTest类

package testing.test;

public class JavaTest 
{
    int i=2;
}
package testing.test;

class JavaTest2 extends JavaTest
{
    public static void main(String[] args) {


        new JavaTest2().add(5);
    }

    void add(int i)
    {
        System.out.println(5+i);
    }
}
这是JavaTest2类,它扩展了JavaTest

package testing.test;

public class JavaTest 
{
    int i=2;
}
package testing.test;

class JavaTest2 extends JavaTest
{
    public static void main(String[] args) {


        new JavaTest2().add(5);
    }

    void add(int i)
    {
        System.out.println(5+i);
    }
}
现在输出是10,实际问题是获取要添加的父类的i值。

这里的问题是您的
add
方法
i
变量声明为参数的类的
i
属性隐藏起来。因此,在
add
方法中使用
i
时,使用的是
i
参数,而不是
i
属性

要注意差异,请将
add
方法更改为:

void add(int i) {
    System.out.println(5+i);
    System.out.println(5+this.i); //this will do the work for you
}
在类构造函数上使用了一个很好的阴影示例:

public class SomeClass {
    int x;
    public SomeClass(int x) {
        //this.x refers to the x attribute
        //plain x refers to x parameter
        this.x = x;
    }
}
评论的后续行动:


明白了,但是如果我拥有与JavaTest2中相同的成员,并执行相同的操作,会发生什么呢

这被称为隐藏,在Oracle的Java教程中有很好的解释:

例如:

class JavaTest2 extends JavaTest {
    int i = 10;
    void add(int i) {
        System.out.println(5+i);
        System.out.println(5+this.i); //this will add 5 to i attribute in JavaTest2
        System.out.println(5+super.i); //this will add 5 to i attribute in JavaTest
    }
}

您指的是作为参数接收的
i
。试试这个.i

void add(int i)
{
    System.out.println(i + this.i);
}

这将在上面的示例中打印
7

您将5传递给
add
方法。这5是5的补充和打印

System.out.println(5+i);
所以这里没什么奇怪的

JavaTest
中初始化的
i
被方法声明中的
i
隐藏。定义使用的局部变量最多。如果您希望该方法使用字段
i
,可以如下更改您的方法:

void add(int j) {
    System.out.println(5+i);
}

add
方法中,超类中的
i
变量不可见。您正在使用一个参数覆盖它,您也调用了
i

尝试用以下方法替换
add()
方法:

void add(int x)
{
    System.out.println(5+i);
}

输出将变为7。实际上,您现在所做的是打印出
5+x

i
内部
add
是从父类继承的
i
参数

  void add(int i) <----------------+
  {                                |
      System.out.println(5 + i); --+

      System.out.println(5 + this.i);  --> member i
  }
void添加(int i)成员i
}
因此,在
添加(5)
之后,它将打印
5+5
->
10

要指示继承的
i
,请尝试改用
this.i

add()函数中的参数与class属性同名

重命名您的参数,它应该可以工作:

void add(int someNumber)
{
     System.out.println(5+i); // result 7
     System.out.println(5+someNumber); // result 10
}

如果在作用域中有一个局部变量(无论从何处引用它都可以访问),它将采用局部变量。由于在超级类(JavaTest)中有一个实例变量,在add方法中有一个参数,因此将采用后者

除非另有要求,通常建议将所有实例变量设置为私有。除此之外,对局部变量和实例变量使用相同的名称是非常糟糕的做法(它认为这称为阴影)。

  • 这是继承的一个简单概念
  • 其中超类的
    方法
    实例变量
    被继承到基类中。

  • i
    是JavaTest类的一个实例变量,该类由其基类继承

    无效添加(int i){

    }


没有任何复杂的逻辑。你只需要打印5+5…@Anan,没有人天生就知道这些东西。例如,如果你发布一个JSF问题,与之相比,你会看起来像一个傻瓜,但不需要对任何人粗鲁(至少不在这个网站上)。@LuiggiMendoza,问题已经改变,看一看,我不能发布更多的问题,如果可能的话,也可以向上投票,允许我发布新问题……但我需要你上次做的解释,你解释得很好,不能编辑已回答的问题。相反,创建一个新的链接,并发布一个指向此链接的链接。此外,这些问题开放给每个人阅读和回答,而不仅仅是一个人。@LuiggiMendoza我不允许发布更多的问题:(明白了,但是如果我在JavaTest2中拥有与我相同的成员…并执行相同的操作,会发生什么情况。您的
JavaTest2
将隐藏
JavaTest
类中声明的属性。