为什么以下代码编译成功并运行?

时间:2015-07-24 06:20:32

标签: java inheritance encapsulation

我在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

9 个答案:

答案 0 :(得分:8)

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

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

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

答案 1 :(得分:2)

名称建议的

访问修饰符只能影响变量/方法的可访问性而不能继承,您无法直接在Child类中访问age变量,因为private但它并不代表儿童对象不存在。

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

为了更好地理解,请查看Controlling Access to Members of a Class

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

答案 2 :(得分:1)

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

默认值

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

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

答案 3 :(得分:1)

对于Parent类,没有约束器,因此JAVA会生成一个defualt约束器。

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

您可以在Parent类中构建此构造函数:

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

您将看到打印时儿童年龄为15岁。

答案 4 :(得分:0)

您正在访问公开getAge()方法并且是合法的。 getAge()的实施是访问private成员,而不是您。

答案 5 :(得分:0)

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

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

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

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

答案 6 :(得分:0)

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 封装的概念。
  • 在父类中定义的
  • public methodsvariables可以在子类中访问。此处有{{1>}概念继承

答案 7 :(得分:0)

加我的几美分。子类无法访问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

答案 8 :(得分:0)

私有成员没有继承权,但我们可以通过公共方法访问它。所以在你的情况下私​​人成员是通过公共方法访问。 并且值的原因是零,因为父类对象的变量age的值不是子类对象。所以当你通过子类对象访问age变量的值时,它会打印变量age的默认值。