对于Java这种语言来说,一般来说,子类可以调用父类中的非private变量,但在一些特殊情况下,

Java语言可以通过父类调用子类的变量

具体的还是请按下面的例子吧!

package com.yonyou.test;

/**
* 测试类
* @author 小浩
* @创建日期 2015-3-2
*/ class Base
{
// 定义了一个名为i的实例变量
private int i = 2;
public Base()
{
this.display(); //注意这里面的this代表当前正在运行的对象,即Derived对象
}
public void display()
{
System.out.println(i);
}
}
// 继承Base的Derived子类
class Derived extends Base
{
// 定义了一个名为i的实例变量
private int i = 22;
// 构造器,将实例变量i初始化为222
public Derived()
{
i = 222; //②
}
public void display()
{
System.out.println(i);
}
}
public class Test
{
public static void main(String[] args)
{
// 创建Derived的构造器创建实例
new Derived(); //①
}
}

  最后的结果是多少呢?没错就是0,是不是很意外,这里你需要明白。

public Base()
{
this.display(); //注意这里面的this代表当前正在运行的对象,即Derived对象
}

  这里面的this指的是当前正在运行的那个对象,那么当前运行的对象是谁?没错,就是Derived对象。

为了确定是Derived,我们可以看下面的代码:

	public Base()
{
System.out.println(this.i); //新增加的变量 其值为2
this.display(); //注意这里面的this代表当前正在运行的对象,即Derived对象
System.out.println(this.getClass());
} //最后结果为:
// 2
// 0
// class com.yonyou.test.Derived

  

但是现在的问题又出现了如果修改上面的代码加入System.out.println(this.i)

如下面的例子:

public Base()
{
System.out.println(this.i); //新增加的变量 其值为2
this.display(); //注意这里面的this代表当前正在运行的对象,即Derived对象
}

  既然这俩this的指的是Derived对象,那为什么其值不是0,而是父类Base对象里面对应变量

的值2呢?

这里涉及到了编译类型和运行时类型相关的内容。当变量的编译类型和运行时类型不同的话,通过该对象访问其所引用对象的实例变量的时候

表现出该实例变量所声明时的类型决定。因为

System.out.println(this.i); //新增加的变量 其值为2

这里的this访问的变量,所以其值为声明它的对象Base的值,即2

但通过通过此实例变量调用它所对应的实例方法的时候,该方法的行为将由它实际所引用的对象来决定。

因为

this.display(); //注意这里面的this代表当前正在运行的对象,即Derived对象

这里的this的实际引用它的对象为Derived,所以其i值为0.

根据java创建对象时初始化对象的时机(http://www.cnblogs.com/xiohao/p/4349833.html),我们知道这时Derived中的变量i还没有初始化,

所以最后的结果为:0

最后提示一下如果是静态方法的话,仅仅序声明它的类型相关,与其它的没有任何关系哦...

下面是对比的例子:

1 静态方法,仅仅与其声明的类型有关

package com.yonyou.test;

/**
* 测试类
* @author 小浩
* @创建日期 2015-3-20
*/ public class Test
{
public static void main(String[] args) {
Base b=new Base();
Base c=new Inherit();
b.a();
b.b();
c.a();
c.b();
}
}
class Base{
static void a( ){System.out.println("A"); }
void b( ){System.out.println("B"); }
}
class Inherit extends Base{
static void a( ){System.out.println("C"); }
void b( ){System.out.println("D"); } }

最后的结果为:A,B,A,D

2.非静态方法正常,与其真正所引用的类型相关

package com.yonyou.test;

/**
* 测试类
* @author 小浩
* @创建日期 2015-3-20
*/ public class Test
{
public static void main(String[] args) {
Base b=new Base();
Base c=new Inherit();
b.a();
b.b();
c.a();
c.b();
}
}
class Base{
void a( ){System.out.println("A"); }
void b( ){System.out.println("B"); }
}
class Inherit extends Base{
void a( ){System.out.println("C"); }
void b( ){System.out.println("D"); } }

结果为:A,B,C,D

上面的话有一些绕,请务必多读几遍,反复揣摩,这样你会更上一层楼。

如果实在不懂也可以发送邮件至:12612455595@qq.com

如果你确实理解了的话,请通过下面的例子测试一下:

package com.yonyou.test;

/**
* 测试类
* @author 小浩
* @创建日期 2015-3-2
*/ class Animal
{
// desc实例变量保存对象toString方法的返回值
private String desc;
public Animal()
{
// 调用getDesc()方法初始化desc实例变量
this.desc = getDesc(); //②
}
public String getDesc()
{
return "Animal";
}
public String toString()
{
return desc;
}
}
public class Wolf extends Animal
{
// 定义name、weight两个实例变量
private String name;
private double weight;
public Wolf(String name , double weight)
{
// 为name、weight两个实例变量赋值
this.name = name; //③
this.weight = weight;
}
// 重写父类的getDesc()方法
@Override
public String getDesc()
{
return "Wolf[name=" + name + " , weight="
+ weight + "]";
}
public static void main(String[] args)
{
System.out.println(new Wolf("灰太狼" , 32.3)); //①
}
}

提示:最后的结果为:

Wolf[name=null , weight=0.0]

测试例子2:

class Base
{
int count = 2;
public void display()
{
System.out.println(this.count);
}
}
class Derived extends Base
{
int count = 20;
@Override
public void display()
{
System.out.println(this.count);
}
}
public class FieldAndMethodTest
{
public static void main(String[] args)
{
// 声明、创建一个Base对象
Base b = new Base(); //①
// 直接访问count实例变量和通过display访问count实例变量
System.out.println(b.count);
b.display();
// 声明、并创建一个Derived对象
Derived d = new Derived(); //②
// 直接访问count实例变量和通过display访问count实例变量
System.out.println(d.count);
d.display();
// 声明一个Base变量,并将Derived对象赋给该变量
Base bd = new Derived(); //③
// 直接访问count实例变量和通过display访问count实例变量
System.out.println(bd.count);
bd.display();
// 让d2b变量指向原d变量所指向的Dervied对象
Base d2b = d; //④
// 访问d2b所指对象的count实例变量
System.out.println(d2b.count);
}
}

  运行结果为:

2
2
20
20
2
20
2

  

好吧,今天就先到这里吧、、、

Java访问子类对象的实例变量的更多相关文章

  1. OC 继承子类对象调用方法机制 子类对象访问父类中的实例变量

    在继承中,子类对象如何调用到正确方法的机制 每一个Objective - C对象都有一个隐藏的指针指向类的代码,当向一个对象发送消息的时候,当前的对象会首先在当前类里去查找相应的方法,如果找到的话,直 ...

  2. 【JAVA】笔记(2)---面向过程与面向对象;类,对象;实例变量,引用;构造方法;

    面向过程与面向对象: 1.面向过程思想的典型栗子是C语言,C语言实现一个程序的流程是:在主函数中一步一步地罗列代码(定义子函数来罗列也是一样的道理),以此来实现我们想要的效果: 2.面向对象思想的典型 ...

  3. java子类对象和成员变量的隐写&方法重写

    1.子类继承的方法只能操作子类继承和隐藏的成员变量名字类新定义的方法可以操作子类继承和子类新生命的成员变量,但是无法操作子类隐藏的成员变量(需要适用super关键字操作子类隐藏的成员变量.) publ ...

  4. Java中的类变量、实例变量、类方法、实例方法的区别

    类变量:形如static int a; 顾名思义,类变量可以理解为类的变量,类变量在类加载的时候就已经给它分配了内存空间,不同于实例变量(int a; ),实例变量是在该类创建对象的时候分配内存的.并 ...

  5. Java中子类对象初始化的过程

    Java中的继承机制看似简单,实际上包含了很多细节.最近在刷题过程中屡屡跳坑,于是自己仔细再学习了一下Java中子类初始化的细节,与大家分享. class Father { Father(){}; } ...

  6. Java中子类对象赋值给父类变量

    1. 在Java中将一个字类对象赋值给父类变量是合法的,这也是实现多态(即方法的动态分派)的前提条件之一. 2. 在Java中父类赋值同样也适用于数组.可以将一个子类数组赋值给一个父类数组变量.但可能 ...

  7. java类与对象_成员变量和局部变量区别

    成员变量和局部变量:1.成员变量:再类中定义,用来描述对象将要有什么.2.局部变量:在类的方法中定义,在方法中临时保存数据.区别:1.作用域不同:  局部:仅限于定义它的方法  成员:整个类中都是可见 ...

  8. java之子类对象实例化过程

    假设现在有这么一个父类: public class Person{ public Person(){} public String name = "tom"; public int ...

  9. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

随机推荐

  1. Linux中各种压缩文件

    .gz格式 压缩: gzip 文件名 解压: gzip -d 欲解压文件名 gunzip 欲解压文件名 说明: 1.只能压缩文件,不能压缩目录 2.压缩和解压的时候不保留原文件 .bz2格式 压缩: ...

  2. 北京君正集成电路的Newton平台--穿戴式

    版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/hellomxj1/article/details/25324125   Newton1开发平台 • 很适合 ...

  3. table control里面各种属性和事件

    [转自]http://blog.csdn.net/hackai886/article/details/7935366 SAP中,Table Control是在Screen中用的最广泛的控件之一了,可以 ...

  4. VHDL基础 学习笔记

    最近一直忙着学校里的活动,所以没怎么更新,上周活动忙完了,正好也借着数电实验的机会,重新学习一下VHDL的编程.以下是转自360doc的教程: ———————————————————————————— ...

  5. P1393 动态逆序对

    题目 P1393 动态逆序对 做题前写篇博客是个好方法 做法 题目规定仅有删除,给每个位置标个号,逆序对+时间轴,显然这是个三维偏序 很久没做过\(cdq\)了,就当模板题讲一下: 按删除的先后顺序为 ...

  6. perl常用字符串函数

    1.$position = index(string,substring,skipchars): 该函数返回子串substring在字符串string中的位置,如果不存在,则返回-1:参数skipch ...

  7. UOJ279 【UTR #2】题目交流通道

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000  作者博客:http://www.cnblogs.com/ljh2000-jump ...

  8. 机器学习(二十四)— 偏差Bias 与方差Variance

    1.首先 Error = Bias + Variance  Error反映的是整个模型的准确度, Bias反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度, Variance反映的是模 ...

  9. python UDP CS demo

    UDP Communication Contents UDP Communication Sending Receiving Using UDP for e.g. File Transfers Mul ...

  10. Java之泛型深解

    泛型的内容确实很多,在上一篇Java之泛型浅解讲到了一些常用的泛型,但是还远远不够,上一篇的内容比较容易理解,这一篇我自己觉得更加难理解一些,因此,我还得想办法让它更加接地气更加容易理解,方便我和源宝 ...