子类和父类定义相同的方法和属性的解析:

子类和父类定义相同的方法只要符合方法覆盖的条件:

子类和父类定义相同属性不会产生覆盖:

解析:

这个问题不仅要考虑变量、静态变量和常量三种情况,还要考虑private、friendly(即不加访问修饰符)、protected和public四种访问权限下对属性的不同影响,private的变量与其它三种访问权限变量的不同,对象无法直接访问私有变量。

子类父类定义相同get,set方法的引起重写(override)。

结论:由于private变量受访问权限的限制,它不能被覆盖。
属性的值取父类还是子类并不取决于我们创建对象的类型,而是取决于我们定义的变量的类型。
friendly、protected和public修饰符并不影响属性的覆盖。
静态变量和静态常量属于类,不属于对象,因此它们不能被覆盖。
常量可以被覆盖。 对于基本类型和对象,它们适用同样的覆盖规律。

java内存管理简图:

静态变量区文本区
存放静态变量存放方法编译时变量运行时变量(类属性)
    

那天crm研发人员开会讨论开发中常见的问题:遇到了一个基类与子类中声明了一个相同名称的属性,最终得出的结论是:子类会覆盖父类的属性,并且初始化子类后,通过父类调用该属性和子类调用该属性的值应该相同。

这个结论是错误的。正确结论为:基类与子类中声明了一个相同名称的属性,基类和子类都可以分别管理自己的属性,且属性值不会被覆盖,即使基类与子类中声明了一个相同名称的静态变量,静态变量的值也不会覆盖。

虽然在子类和父类中定义相同名称的属性,在语义上没有多大意义,但理解背后的原理,对学习java还是很有帮助的。

解释如下:

多态和继承作为java面向对象编程的重要特征及其java类加载和初始化的独特实现机制,

确保了子类属性不会覆盖父类属性,及其属性的值。

目前就假定有一个子类和父类同时声明了一个相同名称的属性。

实例化一个类时new Xyz() 执行以下操作:

a. 为对象分配内存。

b. 执行属性的显式初始化。

c. 执行构造器

d. new 运算符返回对象引用。

 

如果实例化子类,执行步骤ab后,子类执行构造器会自动调用父类构造器,

如果父类还有父类,父类构造器自动调用父类的父类构造器,直到找到基类后,调用基类构造器,基类构造器完成后,返回到子类构造器继续执行子类的构造及其初始话过程。

这个就是java中一个重要的概念:父类委托。

从现象上看:子类实例化后,子类中定义的属性和方法,对于父类来讲,是子类特有的切片。

用我自己的总结的一句话来概括就是,“java类加载和初始化的过程为:一次性分配内存,分层加载”。

读到这里如果对这部分解释还是有疑问的,可以记住结论并搞清楚单个无子类继承的java类的初始化过程,之后再了解一下java的内存管理机制及其类加载机制,有利于深入理解java子类的初始话过程。由于此部分解释是自己理解的一种表达,虽然做过验证,但有错误的地方,请大家指正。

这个与其他语言中的实现机制有区别:html中定义一个相同名称和属性的标签:后者会覆盖前者。

举例说明:单个无子类继承的java类的初始化过程。

构造和初始化对象

调用 new Xyz() 执行以下操作:

a. 为对象分配内存。

b. 执行属性的显式初始化。

c. 执行构造器

d. new 运算符返回对象引用。

举例:

MyDate my_birth = new MyDate(22, 7, 1964);

ü        声明只为引用分配存储空间:

my_birth XXXXX

MyDate my_birth = new MyDate(22, 7, 1964);

ü       使用 new 运算符为 MyDate 分配空间

MyDate my_birth = new MyDate(22, 7, 1964);

my_birth ????

day 0

month 0

year 0

ü        执行构造器

执行匹配的构造器(构造器可以重载),如下所示:

MyDate my_birth = new MyDate(22, 7, 1964);

my_birth ????

day  22

month 7

year 1964

ü        变量赋值

将新创建的对象赋值给引用变量,如下所示

MyDate my_birth = new MyDate(22, 7, 1964);

my_birth 0x01abcdef

day 22

month 7

year 1964

--------------------------------------------------------------------

package haolong;

public class Jilei {
 static int x =10;
public  String public_jtgj="100";
private  String private_jtgj="100";
            String friendly_jtgj="100";
protected String protected_jtgj="100";

public Jilei() {
 System.out.println ("构造父类方法");

}
public void out (){
 System.out.println ("父类方法public_jtgj="+public_jtgj);
 System.out.println ("父类方法private_jtgj="+private_jtgj);
 System.out.println ("父类方法friendly_jtgj="+friendly_jtgj);
 System.out.println ("父类方法protected_jtgj="+protected_jtgj);
 System.out.println ("Jilei:x="+x);
}
public String getPrivate_jtgj() {
 return private_jtgj;
}
public void setPrivate_jtgj(String private_jtgj) {
 this.private_jtgj = private_jtgj;
}
}
-------------------------------------------------

package haolong;

public class Zilei extends Jilei {

 static int x = 20;
 public  String public_jtgj="200";
 private  String private_jtgj="200";
             String friendly_jtgj="200";
 protected String protected_jtgj="200";

 public Zilei() {
  System.out.println ("构造子类方法");

 }
public void out (){
 System.out.println ("该方法在内存中被覆盖掉了");
 System.out.println ("覆盖子类方法public_jtgj="+public_jtgj);
 System.out.println ("覆盖子类方法private_jtgj="+private_jtgj);
 System.out.println ("覆盖子类方法friendly_jtgj="+friendly_jtgj);
 System.out.println ("覆盖子类方法protected_jtgj="+protected_jtgj);
}

 /**
  * @param args
  */
 public static void main(String[] args) {
//  System.out.println("Jilei jl=  new Jilei();");
//  Jilei jl=  new Jilei();
//  jl.out();
//  System.out.println("Zilei j2=  new Zilei();");
//  Zilei j2=  new Zilei();
//  j2.out();  
//  System.out.println("Jilei z2=  new Zilei();");
  Jilei z2=  new Zilei();
  z2.out();
  System.out.println ("public_jtgj="+z2.public_jtgj);
  System.out.println ("private_jtgj="+z2.getPrivate_jtgj());
  System.out.println ("friendly_jtgj="+z2.friendly_jtgj);
  System.out.println ("protected_jtgj="+z2.protected_jtgj);
  
  System.out.println("z2 = (Jilei) z2 ;");
  z2 = (Jilei) z2 ;
  z2.out();
  System.out.println ("public_jtgj="+z2.public_jtgj);
  System.out.println ("private_jtgj="+z2.getPrivate_jtgj());
  System.out.println ("friendly_jtgj="+z2.friendly_jtgj);
  System.out.println ("protected_jtgj="+z2.protected_jtgj);

 }

 public String getPrivate_jtgj() {
  return private_jtgj;
 }
 public void setPrivate_jtgj(String private_jtgj) {
  this.private_jtgj = private_jtgj;
 }
 

}
---------------------------------------------------------------

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值