关于继承中同名属性的问题。
一、java中允许继承中出现同名属性
如下父类和子类中同时都有name变量。
public class test{
public static void main(String[] args){
Student stu = new Student("111","22");
}
}
class People {
String name;
People(){}
People(String name){
this.name = name;
}
}
class Student extends People{
String name;
Student(){}
Student(String name, String name1){
super(name);
this.name = name1;
}
}
内存图如下:
通过内存图我们可以知道,子类对象的内存空间中包括父类型People中使用的name和子类中使用的name,二者是同名变量,但是他们实际上在不同的内存地址。所以二者不会造成编译或执行错误。
二、当子类调用从父类型继承过来的方法的时候,所操作的数据都是父类型特征中的数据。
public class Test{
public static void main(String[] args){
Student stu = new Student("111","22");
System.out.println(stu.getName()); //输出结果111
}
}
class People {
String name;
People() {
}
People(String name) {
this.name = name;
}
public String getName(){
return this.name;
}
}
class Student extends People{
String name;
Student(){}
Student(String name, String name1){
super(name);
this.name = name1;
}
}
为什么会输出父类的特征呢?
- 其实这是因为当子类的对象在调用方法时,先在子类中找方法,没有找到就去父类里面找,所以调用父类的方法,那么使用的当然是父类中的数据。
- 因为我没有看过java底层是怎么处理这块的,但是可以合理推理:
1、当子类与父类的属性不重名的情况下,那么当我们调用父类继承过来的setter和getter方法,操作的数据我们肯定不会混淆。例如我把子类中的数据改成String sex,你肯定不会混淆,这个时候子类对象调用setName肯定操作的是内存图中父类的那部分特征。现在只不过是将子类的名字改了而已,并没有什么影响。父类中继承过来的函数操作的仍然是父类的那部分特征。
2、况且你要明白的是,父类中定义的方法并不是单纯为了让子类去调用的,同时为了父类的对象,所以不论是父类的对象去调用也好,或者子类的对象去调用也好,SUN公司不可能去开发两种不同的机制,必然是使用的同一种底层。那么既然父类对象去调用setter and getter是访问的父类的属性,那么子类对象去调用继承过来的方法也是访问的父类的属性。
三、综上所述:不要把子类从父类中继承过来的方法当作是在子类的代码里复制粘贴了一份,这个只是帮助你理解什么是继承。而实际的底层操作过程中,子类继承过来的方法也是相当于去调用父类中的方法,我觉得这样理解是正确的。
如果有人问,上面的代码中如果我想get子类的name,怎么办?很容易,我们可以在父类中的getName代码复制粘贴到子类,这个就是常说的覆盖了。
既然覆盖了,子类对象调用getName的时候,先在子类中找,找到了,就执行。
那么有人又问了,那我还想访问父类中的name怎么办?我靠,你真事儿。也有办法那就是通过super关键字在子类中调用父类中getName这个方法。
public class Test{
public static void main(String[] args){
Student stu = new Student("111","22");
System.out.println(stu.getName()); //输出结果22
System.out.println(stu.getFatherName()) // 输出结果111
}
}
class People {
String name;
People() {
}
People(String name) {
this.name = name;
}
public String getName(){
return this.name;
}
}
class Student extends People{
String name;
Student(){}
Student(String name, String name1){
super(name);
this.name = name1;
}
public String getName(){
return this.name;
}
public String getFatherName(){
return super.getName();
}
}