为啥下面的代码编译运行成功? [复制]
Posted
技术标签:
【中文标题】为啥下面的代码编译运行成功? [复制]【英文标题】: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
变量
【参考方案1】:
私有成员没有被继承,但是访问它的公共方法是的。
当您创建Child
类型的对象时,如果不能直接使用,也会创建超类的所有变量。
如果超类中有公共方法,您可以从子类中访问它们。如果这些方法访问超类的私有变量值,您可以通过公共方法间接访问它们。
【讨论】:
谢谢,但是由于该方法现在已被继承并且正在从子类实例中调用它,它不只是在自己的范围内查找变量吗? 不,超类的公共方法体可以访问私有变量,也可以访问超类的其他私有方法。实现细节隐藏到不知道如何收集数据的子类中。【参考方案2】:访问修饰符顾名思义只能影响变量/方法的可访问性而不是继承,您不能直接在 Child 类中访问 age
变量,因为它是 private
但它不会t 表示子对象不存在。
因此,在您的情况下,这两个公共方法都可以从两个类中访问,但在您的 Child 类中,您不能直接使用 age
,除非您将其访问修饰符更改为 protected
或 public
更多了解请看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;
不能在类外访问私有变量。但我们可以通过getter
和setter
访问它。 OOP
封装的概念在这里出现。
在Parent类中定义的publicmethods
、variables
可以在子类中访问。 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 的值是父类对象而不是子类对象。因此,当您通过子类对象访问年龄变量的值时,它会打印变量年龄的默认值。
【讨论】:
以上是关于为啥下面的代码编译运行成功? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
使用部分函数时并未include其所在头文件,但是能编译成功且能运行,为什么?
ASP.NET编译成功后,为啥有些功能不会执行?麻烦高手解答!