Java 为什么下面的代码编译并运行成功?
我有两个JAVA类: 父类:Java 为什么下面的代码编译并运行成功?,java,inheritance,encapsulation,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{ pub
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());
}
}
子类:
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
?您正在访问getAge()
方法,该方法是公共的合法的。getAge()
的实现是访问它的私有成员,而不是您。编程语言最基本的方面之一是如何初始化数据。对于Java,这是在语言规范中明确定义的。对于字段和阵列组件,创建项时,系统会自动将其设置为以下默认值:
numbers: 0 or 0.0
booleans: false
object references: null
这意味着显式地将字段设置为0、false或null(视情况而定)是不必要和冗余的。由于包含此语言功能部分是为了减少重复编码,因此充分利用它是一个好主意。坚持字段应显式初始化为0、false或null是一种习惯用法,这可能不适合Java编程语言
此外,将字段显式设置为0、false或null甚至可能导致同一操作执行两次(取决于编译器) 继承:您从方法
获取值,而不是从变量
获取值
默认值:
- 类类型(非原语,对象):
null
- 基元类型(int、float等):0
请参考Java文档了解继承:私有成员未被继承,但访问它的公共方法是
当您创建类型为Child
的对象时,如果不能直接使用,也会创建超类的所有变量
如果超类中有公共方法,则可以从子类访问它们。如果这些方法访问超类的私有变量值,您可以通过公共方法间接访问它们。对于父类,没有constractor,因此JAVA生成default constractor
当孩子延伸父母时,他实际上是先去他的父母那里
您可以在父类中生成此构造函数:
public Parent(){
this.age = 15;
}
当你打印出来的时候,你会看到孩子的年龄是15岁
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
封装的概念
- 公共
方法
,父类中定义的变量
可以在子类中访问。这里有OOP
继承的概念
访问修饰符顾名思义,只能影响变量/方法的可访问性而不是继承性,您不能直接在子类中访问age
变量,因为它是private
,但这并不意味着它不存在于子对象中
因此,在您的情况下,两个公共方法都可以从两个类中访问,但在您的子类中,您不能直接使用age
,除非您将其访问修饰符更改为protected
或public
为了更好地理解,请看一看
你也可以检查一下,加上我的几美分。子类无法访问父类的private
可变年龄部分。但是年龄状态仍然是子对象的一部分。您可以使用get和set方法进行访问。为了进一步说明,您可以在child对象上调用setAge()
,以设置适当的child年龄
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
私有成员不是继承的权利,但我们可以通过公共方法访问它。所以在您的情况下,私有成员是通过公共方法访问的。
而之所以取值为零,是因为变量年龄的取值由父类对象而不是子类对象决定。因此,当您通过子类对象访问age变量的值时,它会打印变量age的默认值。您在此处调用了public
方法而不是private
变量。谢谢,但由于该方法现在已被继承,并且正在从子类实例调用,它是否只会在自己的范围内查找变量?否,超类的公共方法的主体可以访问超类的私有变量和其他私有方法。实现细节隐藏在不知道如何收集数据的子类中。