【安卓学习笔记】JAVA基础Lesson9-对象的转型

对象的转型是面向对象的多态性的体现。

转型分为:

对象的向上转型:将子类的对象赋值给父类的引用

对象的向下转型:将父类的对象赋值给子类的引用


1、对象的向上转型

class Lesson9_father{
	String str;
	int num;
	
	void Function(){
		System.out.println("the father_str is " + this.str + ",the father_num is" + this.num);
	}
}

class Lesson9_son extends Lesson9_father{
	char ch;
	
	void Fun_son(){
		
	}
	void Function(){
		super.Function();
		//System.out.println("the son_str is " + this.str + ",the son_num is" + this.num);
		System.out.println("the son_char is " + this.ch );
	}
}

class Test{
	public static void main(String args []){
		
		Lesson9_son a = new Lesson9_son();
		Lesson9_father b = a;
	}
}

如上三段代码:分别是定义的父类、子类和主函数

在主函数中首先:

Lesson9_son a = new Lesson9_son();

这行代码先是声明了一个 Lesson9_son的引用a并调用Lesson9_son构造函数生成了一个Lesson9_son类型的对象赋值给了a;

Lesson9_father b = a;

这行代码是声明了一个Lesson9_father类型的引用b并把a赋值给了b;

在内存中的示意图如下:


在JAVA中,一个引用能够调用哪些成员变量和成员函数,取决于这个引用的类型。所以在上述测试代码中:对象b是父类,在父类中只有两个成员变量和一个成员函数:

	String str;
	int num;
	void Function(){
	...
	}

在子类当中出去继承以上变量和函数以外还有

char ch;//变量
void Fun_son(){//函数
	
}

所以在这个基础上推断,父类对象b是不能调用子类中的变量ch和函数Fun_son()的,因为在父类里面根本就没有这个ch和Fun_son();但是这里问题又出现了,子类和父类里面都有Function函数,存在函数的复写(override)关系。这时候如果写成b.Function();

Lesson9_son a = new Lesson9_son();
Lesson9_father b = a;

b.str = "abc";
b.num = 123;
b.Function();

结果会是什么?经过验证后的结果如下:

D:\Android\src>javac Lesson9.java

D:\Android\src>javac Test.java

D:\Android\src>java Test
the father_str is abc,the father_num is123
the son_char is

D:\Android\src>

上述结果可以看出,父类里面只有第一句打印,子类里面同时有两句打印,这很明显是子类中的函数,这里的变量ch并没有值,是因为父类引用b并不能给ch赋值,主函数开始执行到打印输出并没有给ch赋值。

这里先把概念写出来:一个引用调用的是哪一个方法,取决于这个引用所指向的对象。

然后再解释:

首先b是a的引用,而a是子类的对象,父类的引用b只是指向的子类引用a所指的对象,所以这个a所调用的成员变量、成员函数实际上都是a的成员变量和成员函数;到此,我还是觉得云里雾里,于是我又写了以下代码测试:

class Test{
	public static void main(String args []){
		
		Lesson9_son a = new Lesson9_son();
		Lesson9_son b = new Lesson9_son();
		a.ch = 'a';
		b.ch = 'b';
				
		Lesson9_father A = a;		
		A.str = "AAA";
		A.num = 111;
		A.Function();

		A = b;
		A.str = "BBB";
		A.num = 222;
		A.Function();
		
		A = a;
		A.Function();
	}
}

我先后定义一个子类的对象a,b,先后把他们父类引用A并对变量赋值然后打印,注意这里的A先是指向的a赋值然后打印,然后让A指向b赋值并打印,然后再让A指向a并打印,从结果发现这跟C语言上的指针比较类似。

测试结果如下:

D:\Android\src>javac Lesson9.java

D:\Android\src>javac Test.java

D:\Android\src>java Test
the father_str is AAA,the father_num is111
the son_char is a
the father_str is BBB,the father_num is222
the son_char is b
the father_str is AAA,the father_num is111
the son_char is a

D:\Android\src>

这里说明一下:对于向上转型,可以直接定义父类引用使用子类的构造函数;

例如:

Lesson9_son a = new Lesson9_son();
Lesson9_father A = a;

Lesson9_father A = new Lesson9_son();

这两个表达的意思是一样的。

/*******************************************************华丽分割线***********************************************************/

2、对象的向下转型

如:

Lesson9_son a = Lesson9_son();
Lesson9_father A=a;
Lesson9_son b = (Lesson9_son)A;

小结:

1.向下转型的前提是向上转型;

2.在向下转型的时候加上强制转换,(Lesson9_son)A中的Lesson9_son就是强制转换的体现;

3.直接生成的父类对象是无法转型到子类的类型的;

By Urien 2017年8月29日 19:46:43

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值