【问题标题】:Why does following code compile and run successfully? [duplicate]为什么下面的代码编译运行成功? [复制]
【发布时间】:2015-10-14 17:06:20
【问题描述】:

我有 2 个 JAVA 课程:

父类:

public class Parent {
    private int age;

    public void setAge(int age) {           
        this.age = age;
    }

    public int getAge(){
        return this.age;
    }       
}

儿童班:

public class Child extends Parent{      

    public static void main(String[] args){

        Parent p = new Parent();
        p.setAge(35);
        System.out.println("Parent   "+p.getAge());

        Child c = new Child();
        System.out.println("Child  " + c.getAge());         
    }
}

输出是:

  Parent   35
  Child     0

私有成员在 JAVA 中不被继承 在子类实例上调用getAge()方法时,为什么它运行成功,甚至输出为0

【问题讨论】:

  • 你在这里调用了public方法而不是private变量

标签: java inheritance encapsulation


【解决方案1】:

私有成员没有被继承,但是访问它的公共方法是的。

当您创建Child 类型的对象时,如果不能直接使用,也会创建超类的所有变量。

如果超类中有公共方法,您可以从子类中访问它们。如果这些方法访问超类的私有变量值,您可以通过公共方法间接访问它们。

【讨论】:

  • 谢谢,但是由于该方法现在已被继承并且正在从子类实例中调用它,它不只是在自己的范围内查找变量吗?
  • 不,超类的公共方法体可以访问私有变量,也可以访问超类的其他私有方法。实现细节隐藏到不知道如何收集数据的子类中。
【解决方案2】:

访问修饰符顾名思义只能影响变量/方法的可访问性而不是继承,您不能直接在 Child 类中访问 age 变量,因为它是 private 但它不会t 表示子对象不存在。

因此,在您的情况下,这两个公共方法都可以从两个类中访问,但在您的 Child 类中,您不能直接使用 age,除非您将其访问修饰符更改为 protectedpublic

更多了解请看Controlling Access to Members of a Class

您也可以查看Do access modifiers prevent inheritance?

【讨论】:

    【解决方案3】:

    继承:您从method 获得价值,而不是从variable

    默认值

    • 类类型(非原始,对象):null
    • 原始类型(int、float 等):0

    关于继承请参考 Java 文档:https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

    【讨论】:

      【解决方案4】:

      对于 Parent 类没有构造函数,因此 JAVA 会创建一个默认构造函数。

      当 Child 扩展 Parent 时,他实际上首先去他的父 constactor。

      你可以在父类中构建这个构造函数:

      public Parent(){
         this.age = 15;
      }
      

      当您打印它时,您会看到孩子的年龄为 15 岁。

      【讨论】:

        【解决方案5】:

        您正在访问 public 且合法的 getAge() 方法。 getAge() 的实现是访问它的 private 成员,而不是你。

        【讨论】:

          【解决方案6】:

          编程语言最基本的方面之一是它如何初始化数据。对于 Java,这是在语言规范中明确定义的。对于字段和数组组件,在创建项目时,系统会自动将其设置为以下默认值:

          numbers: 0 or 0.0
          booleans: false
          object references: null 
          

          这意味着将字段显式设置为 0、false 或 null(视情况而定)是不必要且多余的。由于包含此语言功能是为了部分减少重复编码,因此充分利用它是一个好主意。坚持将字段显式初始化为 0、false 或 null 是一种习惯用法,可能不适合 Java 编程语言。

          此外,将字段显式设置为 0、false 或 null 甚至可能导致执行两次相同的操作(取决于您的编译器)。

          【讨论】:

            【解决方案7】:
            public class Child extends Parent{      
            
                public static void main(String[] args){
            
                    Parent p = new Parent();
                    p.setAge(35);
                    System.out.println("Parent   "+p.getAge());
            
            
                    Child c = new Child();
                    System.out.println("Child  " + c.age);      //can't access private 
                    System.out.println("Child  " + c.name);     //can access public variable
                    System.out.println("Child  " + c.getAge()); //can access public method
                    System.out.println("Child  " + c.getName());//can,t access private method 
            
                }
            }
            
            class Parent {
                private int age;
                public String name;
            
                public void setAge(int age){
            
                    this.age = age;
                }
            
                private String getName(){
                    return name;
                }
            
                public int getAge(){
                    return this.age;
                }
            
            }
            
            • 不能在类外访问私有变量。但我们可以通过gettersetter 访问它。 OOP 封装的概念在这里出现。
            • 在Parent类中定义的publicmethodsvariables可以在子类中访问。 OOP 继承的概念在这里出现。

            【讨论】:

              【解决方案8】:

              加上我的几美分。子类无法访问父类的private 变量年龄。但是年龄状态仍然是 Child 对象的一部分。您可以使用 get 和 set 方法访问。为了进一步说明,您可以在子对象上调用setAge() 来设置孩子的适当年龄。

              public class Child extends Parent {
                  public static void main(String[] args) {
                      Parent p = new Parent();
                      p.setAge(35);
                      System.out.println("Parent "+p.getAge());
              
                      Child c = new Child();
                      c.setAge(20);
                      System.out.println("Child " + c.getAge());
                  }
              }
              

              输出:

              Parent 35
              Child 20
              

              【讨论】:

                【解决方案9】:

                Private 成员没有继承权,但我们可以通过 public 方法访问它。因此,在您的情况下,私有成员是通过公共方法访问的。 而 value 的原因是零,因为变量 age 的值是父类对象而不是子类对象。因此,当您通过子类对象访问年龄变量的值时,它会打印变量年龄的默认值。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-05-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-19
                  相关资源
                  最近更新 更多