举例说明对象属性的java引用传递举例方法

java中父类对象引用指向子类对象_百度知道
java中父类对象引用指向子类对象
1.从对象的内存角度来理解.假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,里面的变量需要占用0.5M内存.现在通过代码来看看内存的分配情况:2.f = new Father();//系统将分配1M内存.Son s = new Son();//系统将分配1.5M内存!因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用父类的方法.3.Son s1 =//s1指向那1.5M的内存.Father f1 = (Father)s;//这时f1会指向那1.5M内存中的1M内存,即是说,f1只是指向了s中实例的父类实例对象,所以f1只能调用父类的方法(存储在1M内存中),而不能调用子类的方法(存储在0.5M内存中).Son s2 = (Son)f;//这句代码运行时会报ClassCastException.因为f中只有1M内存,而子类的引用都必须要有1.5M的内存,所以无法转换.Son s3 = (Son)f1;//这句可以通过运行,这时s3指向那1.5M的内存.由于f1是由s转换过来的,所以它是有1.5M的内存的,只是它指向的只有1M内存.4.static
顾名思义,就是静态的,他是方法的,他属于这个类,由于是类的方法,他可以直接引用类名来引用方法,也可以通过类的对象来引用这个方法,他既不能被子类覆盖,也不能被子类继承。简单的说,他是在编译的时候就和类帮定在一起了,不能被运行时动态加载。 对子类与父类的static问题 ——没覆盖也没继承,子类存有指向父类的引用 对于private ——该方法或属性只能在该类内使用
其他类似问题
为您推荐:
提问者采纳
&#47? 子类的,从而可以在不影响使用者的前提下改变类的内部结构; } } &#47,还增加了几个函数(例如 myFun()) 分析。一个基类的对象引用; 进行强制转化,这样子合情合理;&#47,如果在子类中”重写“了父类中的变量。 * 另外,a1和c2;/这代表什么意思呢?
很简单;如果父类类型的引用中调用了func2()方法;&#47,抽象类的子类必须覆盖实现超类中的所有的抽象方法,也就是说被子类覆盖的方法;测试类 public class Test{
public static void main(String args[]){
F),不知道它是什么;
这2句话, b,但是势必在功能上有很大的限制、不能把父类对象引用赋给子类对象引用变量 BaseClass a2=new BaseClass()、继承和多态;定义超类superA class superA { int i = 100,则会出错。 2。
Java的所有函数。 * java的这种机制遵循一个原则;所以在父类类型的引用中调用时. 对接口来说:发送消息给某个对象;同时,首先要知道什么是“向上转型”,这个方法将不再有效
&#47。 DerivedC c2=new DerivedC()。也许有人会问、变量不能被重写(覆盖);
father;同样(2)调用的是子类subC的成员方法fun(),不要被上例中(1)和(2)所迷惑;
child.、使用父类类型的引用指向子类的对象,派生类与基类间有IS-A的关系(即“猫”is a “动物”);
father = new Son1(),Java引入了多态性的概念以弥补这点的不足;(动态连接;),可以总结它为。
继承是为了重用父类代码;&#47!这就是多态的表现;打印结果将会是什么.run()这个方法 输出的
是 &quot?
上面的程序是个很典型的多态的例子。送你了,别打了,此外,或者说指向类A的一个子类.fun();&#47、动态调用)
四、基本概念 多态性。 这里你可以这样理解;重写父类打孩子方法
public void hitChild(){
System、记住一个很简单又很复杂的规则,重写了父类的func2()方法;): 一个指针指向一张表格; 定义superA的子类subB class subB extends superA { int m = 1,由于父类中没有func1(int i);
} } 都调用了相同的方法.println(&quot,这个不难理解,成为通用类型BaseC
} } / 定义superA的子类subC class subC extends superA { int n = 1;&#47,自然表现形式就不一样,父类类型的引用child就不能调用func1(int i)方法,一个类之能有一个父类.eat().println(&quot.println(&quot.play()将执行子类还是父类定义的方法;对于父类中定义的方法,抽象类和接口也是解决单继承规定限制的重要手段.out,同是跑;由于在父类中没有定义这个方法,原因之一是它在类的继承问题上和C++不同,又可以抽取父类的共性,编译器自动将子类实例向上移动;
father.fun(200), * 也就是说被子类覆盖的方法,所以Animal类型的引用是可以指向Cat类型的对象的? &&#47,执行该方法时;/
二:Animal a = new Cat(),因为下面的子类中重写了该方法
&#47,因为父类引用指向子类对象的时候。但当我这样定义时;)。由于Cat是继承自它的父类Animal,DerivedC类在继承BaseClass中定义的函数外.func1(68)是不对的
public void func1(int i){
System.println(&quot: * 为什么子类的类型的对象实例可以覆给超类引用!& } } &#47,相同的消息(也就是调用相同的方法)会有不同的结果,那么在编译时会报错;
father = new Son3().hitChild()。 ****************************************************************************************************************************多态详解(整理) 19;&#47, * 被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法。Java之所以引入多态的概念,不同的对象。通过该语句,明白了这些还不够,指向新建的Cat类型的对象;父类有一个打孩子方法
public void hitChild(){
} } &#47,所以。 Java把类型信息和函数信息分开放。 二: 当你使用父类引用指向子类的时候这个是我很早之前学习到“多态”时候整理的笔记;
} } &#47.out,而对于子类中定义而父类中没有的方法,另外一个指向类对象;),那么在调用这个方法的时候;我跑,虽然写成a。具体的实现方法同上例。我可以通过Cat c = new Cat(),动态运行的时候又根据型别去调用了子类的方法;&#47!Java的多态性面向对象编程有三个特征,如果子类中重写了该方法,一个类型引用只能引用引用类型自身含有的方法和变量,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下。那么什么是多态呢。子类Child继承了父类F void fun(int cc) { System,方法名相同; } } class Test { public static void main(String[] args) { superA a = new superA(),”重写“的概念只针对方法;/ DerivedC c1=a2,这就是动态连接. void fun(int j) { j = i,所以 ahuman,它继承了Animal类.out. 如果a是接口A的一个引用.func1()! &quot,不一样(这个是方法覆盖的例子)
class Test{
void out(String str){输出 str}
void out(int i){输出 i}
这个例子是方法重载,属性较父类更独特;
&#47。而继承的表现就是多态;所以在下面的main方法中child,才可以被父类类型的引用调用:我知道错了: &#47.
1个行为;重写父类打孩子方法
public void hitChild(){
System,定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,即封装;This is superA&quot?
很显然,并声明了一个Human的引用;。举例说明,这就是多态,但是由于(1)中的a被b赋值.。 虚拟函数调用是经过虚拟函数表间接调用的,DerivedC中均有定义.一;);CCC&quot,但是这个被调用的方法必须是在超类中定义过的、Java与C++多态性的比较 jvm关于多态性支持解决方法是和c++中几乎一样的,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,但是向下转型却不是,那么,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2(),相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。
我定义了一个子类C/&#47,如果子类继承的超类是一个抽象类,这样每个子类里重写的代码不一样;play()在BaseCBaseClass 基类.下面是另一种实现多态的方法-----------重写父类方法1.println(&quot。四,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用; &#47. 如果a是类A的一个引用;这是大熊猫; System,让它去指向Man这个对象
意思是说,a必须指向实现了接口A的一个类的实例;),也就是向下转型!&quot,需要我们自己定义强制进行,同时为实现多态性作准备,你把它当成其父类 动物看,将根据a这个对象引用实际的类型来获取对应的方法; BaseClass a1= c2,都是用后期绑定?
方法的重写;* * 上述代码中subB和subC是超类superA的子类?我做错什么了。 例如,子类会重新设置自己的虚拟函数表,父类类型的引用可以调用父类中定义的所有属性和方法。而子类重写了func2()方法!希望对你有用,类实例的引用就是指向一个句柄(handle)的指针.println(&&#47,所以才得以实现多态的,所以一般子类在功能上较父类更强大:
方法重载 overloading 以及 方法重写(覆盖)override
class Human{
void run(){输出 人在跑}
class Man extends Human{
void run(){输出 男人在跑}
这个时候.hitChild(),实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表.,这确实给其带来的非常强大的功能。 三; void fun(int aa) { System。看下面这段程序,除了被声明为final的,那么后者就是前者是父类,而Human没有这个方法; &#47.println(&quot,所以它不能被父类类型的引用调用
&#47,那么,所以;AAA&quot.JAVA里没有多继承。 * 不过;
/的确实例化了Man对象,那是因为采用了后期绑定, 在调用eat方法时;&#47。所以。在运行时期;),表明该对象所属的类型),同时保护了数据,并重载了父类的func1()方法;子类1 public class Son1 extends Father{
&#47。重载后的func1(int i)和func1()不再是同一个方法,它表示我定义了一个Animal类型的引用.
比如去动物园;This is subC&
这样我等于实例化了一个Man的对象;取而代之的是将调用子类中重写的func2()方法
public void func2(){
System,向上转型是自动进行的。从父类继承的虚拟函数和子类自己的虚拟函数。 c1=(DerivedC)a2。
对于多态,当然也就不能被实例化了 *&#47,最后执行的是子类的方法的、重载与动态连接构成多态性;这是什么动物;&#47。这样用父类的变量去引用不同的子类; subB b = new subB(); a =)。而假若子类的这个方法在父类中并没有定义。 1。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了?因为子类是对父类的一个改进和扩充;/ a =为什么打我.println(&quot,将会调用子类中的这个方法。 4,把 Man这个对象当 Human看了。Java中在继承以后。所以才有多态性、Java多态性实现机制 SUN目前的JVM实现机制,那么。 其实这并不矛盾, * 但是可以创建抽象类的对象引用指向子类对象,参数表不同 男人在跑 &&#47: 1 接口 和 实现接口并覆盖接口中同一方法的几不同的类体现的 2 父类 和 继承父类并覆盖父类中同一方法的几个不同子类实现的,出现了不同的结果。 你可能说这个规则不对的, *
father = new Son2(),应该是“CCC”,就是最好的证明;func1(int i)是对func1()方法的一个重载
&#47,它是无可奈何的, 只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是a1和c2拥有同一块数据内存块和不同的函数表,那么父类类型的引用将会调用子类中的这个方法,
这个大熊猫对象,后者允许多继承,你看见了一个动物,a可以指向类A的一个实例。 在a1=c2的时候。那么这样做有什么意义呢. 3.out,而在子类里可以重写父类的方法(例如方法print()),这个句柄是一对指针;&#47,还用人在跑举例
Human ahuman=new Man().out,虽然抽象类不能通过new操作符实例化;
public class PolymorphismTest {
public static void main(String[] args) {
Father child = new Child();子类3 public class Son3 extends Father{
&#47,即子类覆写了该方法 分析.fun(100)、该引用只能调用父类中定义的方法和变量;&#47: * &quot,DerivedC是继承自BaseClass的子类 a1。 通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用:当超类对象引用变量引用子类对象时、如果子类中重写了父类中的一个方法,你打不着? 自动实现向上转型, * 指向了子类subB的一个实例;/ * a,被赋予不同的子类对象引用.这是父类中的func2()方法。一个父类可以有多个子类;父类 public class Father{
/ a,但是复杂的继承关系也给C++开发者带来了更大的麻烦; &#47,但是利用某种技术来区别;子类2 public class Son2 extends Father{
如果在子类 Man下你 写了一些它独有的方法 比如 eat();func2()重写了父类Father中的func2()方法
&#47,不同的对象,这个虚拟函数表中的项目有由两部分组成;
father,为了规避风险.实例.out,多态也是面向对象编程的精髓所在; 另一个指针指向一块从java堆中为分配出来内存空间.hitChild(); &出错 在java里面、总结 1;&#47:一,Java只允许单继承,这样才可以。
那么该程序将会打印出什么样的结果呢。 2.out。这样做虽然保证了继承关系的简单明了; } } / 以上大多数是以子类覆盖父类的方法实现多态,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。 java 的这种机制遵循一个原则; a,但知道它的父类是动物;&#47.:This is superA&quot:当超类对象引用变量引用子类对象时,我们在类Test中声明了3个引用变量a,其实jvm已经使用了编译器产生的类型信息调整转换了;为什么(1)和(2)不输出,以实现运行时多态性,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法;&#47。同时,因而(1)所调用的fun()实际上是子类subB的成员方法fun().
这种方式下要注意 new Man()。
要理解多态性,情况是类似的.play();BBB&quot,因为不知道它是大熊猫;实例化一个Cat的对象。 * 所以,他们具体体现出来的方式不一样:class Father{
public void func1(){
func2():29多态是通过,一定要注意 强制类型转换 ((Man)ahuman)!& subC c = new subC(), * 它覆盖了超类superA的成员方法fun().println(&
class Child extends Father{
&#47, * 但是这个被调用的方法必须是在超类中定义过的;
比如,那么必然是子类中重写的这个方法
public void func2(){
System,让该对象自行决定响应何种行为,仍然是存在两个句柄,将表现出不同的行为;This is subB&quot、通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用;/重写父类打孩子方法
public void hitChild(){
System, &quot, * 否则子类必须被abstract修饰符修饰。
封装隐藏了类的内部实现机制
提问者评价
谢谢!!!解释得很详细
其他4条回答
父类类型的引用指向子类的对象。你的gettest3这个方法是子类独有的,但是如果自己的方法被子类覆盖了,父亲不会用,就用儿子的。儿子独有的,那么调用的就是子类的,所以父类类型的引用test3用不了。就你这个test3。省点钱是点,儿子有父亲一样的,就是自己用自己的我给你讲讲啊,它只能调用自己的方法,你记住,哈哈。 简单的说
Test2 test3=new Test3();你把test3实例化成父类了,但getTest3()方法是子类Test3里的方法,父类无法调用子类的方法,子类可以调用父类的方法。如果你Test3 test3=new Test3();这么实例化就不会报错了。
Test3 t3 = (Test3)test3;System.out.println(t3.getTest3());
本质上还是为了程序容易扩展。
您可能关注的推广
java的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁js对象属性方法的调用问题
[问题点数:40分,结帖人unregret123456]
js对象属性方法的调用问题
[问题点数:40分,结帖人unregret123456]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2016年6月 Web 开发大版内专家分月排行榜第二2016年5月 Web 开发大版内专家分月排行榜第二2016年4月 Web 开发大版内专家分月排行榜第二2016年2月 Web 开发大版内专家分月排行榜第二2015年9月 Web 开发大版内专家分月排行榜第二2015年7月 Web 开发大版内专家分月排行榜第二2015年6月 Web 开发大版内专家分月排行榜第二2015年4月 Web 开发大版内专家分月排行榜第二2015年3月 Web 开发大版内专家分月排行榜第二2015年2月 Web 开发大版内专家分月排行榜第二
2016年1月 Web 开发大版内专家分月排行榜第三2015年12月 Web 开发大版内专家分月排行榜第三2015年11月 Web 开发大版内专家分月排行榜第三2015年10月 Web 开发大版内专家分月排行榜第三2015年5月 Web 开发大版内专家分月排行榜第三2015年1月 Web 开发大版内专家分月排行榜第三2014年12月 Web 开发大版内专家分月排行榜第三
2016年6月 Web 开发大版内专家分月排行榜第二2016年5月 Web 开发大版内专家分月排行榜第二2016年4月 Web 开发大版内专家分月排行榜第二2016年2月 Web 开发大版内专家分月排行榜第二2015年9月 Web 开发大版内专家分月排行榜第二2015年7月 Web 开发大版内专家分月排行榜第二2015年6月 Web 开发大版内专家分月排行榜第二2015年4月 Web 开发大版内专家分月排行榜第二2015年3月 Web 开发大版内专家分月排行榜第二2015年2月 Web 开发大版内专家分月排行榜第二
2016年1月 Web 开发大版内专家分月排行榜第三2015年12月 Web 开发大版内专家分月排行榜第三2015年11月 Web 开发大版内专家分月排行榜第三2015年10月 Web 开发大版内专家分月排行榜第三2015年5月 Web 开发大版内专家分月排行榜第三2015年1月 Web 开发大版内专家分月排行榜第三2014年12月 Web 开发大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。以下试题来自:
单项选择题在定义类的基本命令DEFINE CLASS中,如果引用了关键字PROTECTED,就可以保护类定义中相应的对象、属性和方法程序。访问由该关键字说明的属性、方法程序和对象的方法是______。A.用THI<属性或方法程序>访问B.用<对象>.<属性或方法程序>访问C.用<对象>.<属性或方法程序>访问D.用类定义中的其他方法访问
为您推荐的考试题库
你可能感兴趣的试题
1A.0B.1C.2D.不确定2A.UPDATE STUD姓名="王小鱼"WHERE 姓名="王大川"B.UPDATE STUD姓名="王大川"WHERE 姓名="王小鱼"C.UPDATE STUD SET 姓名="王小鱼"WHERE姓名="王大川"D.UPDATE STUD SET姓名="王大川"WHERE姓名="王小鱼"3A.ABdbfB.STUidxC.PAbakD.WP_SKprg4A.INSERT语句中列名的顺序可以与表定义时的列名顺序一致B.INSERT语句中列名的顺序可以与表定义时的列名顺序不一致C.INSERT语句中值的顺序可以与列名的顺序不一致D.INSERT语句中值的顺序必须与列名的顺序一致5A.ValueB.TopC.RowsourceD.Rowsourcetype
热门相关试卷
最新相关试卷<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&举例说明JavaScript中的实例对象与原型对象
作者:zxsrendong
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了JavaScript中的实例对象与原型对象,针对constructor属性和prototype属性展开来讲,需要的朋友可以参考下
首先声明:javascript中每个对象都有一个constructor属性和一个prototype属性。constructor指向对象的构造函数,prototype指向使用构造函数创建的对象实例的原型对象。
function Person(){
var person = new Person();
Person.prototype = {
constructor : Person,
name : 'zxs',
sayName : function(){alert(this.name)}
person.sayName();
在这段代码中会报错,sayName() is not defined。根据javascript高级程序设计第二版的解释,是因为重写的原型切断了构造函数与最初原型之间的联系。但是我们调整一下上面语句的顺序。如下:
function Person(){
//var person = new Person();
Person.prototype = {
constructor : Person,
name : 'zxs',
sayName : function(){alert(this.name)}
/*===========================================================*/
var person = new Person();
/*===========================================================*/
person.sayName(); // zxs
alert(person.constructor) //function Object() { [native code]} or function Person() {} 取决与蓝色的语句是否有效
注意上面两段代码等号中间的语句。按第二段的顺序写代码,将会输出 ”zxs“,这个结果说明在第一种情况下报错并不能说明是因为切断了构造函数与原想之间的联系引起的。
Person.prototype = {}
本来就是一种定义对象的方法,而且在javascript中每个对象的constructor属性都默认的指向Object构造函数,这也就不难说明重写原型对象确实切断了构造函数与最初原型之间的联系,但并不能说明这种联系被切断之后 person就不能访问到sayName()函数。
现在有这样的假设:函数的prototype属性所指向的原型对象,与我们显示新建的原型对象并不是完全等同的。当我们调用函数的时候会创建一个原型对象,此时会首先查找当前环境中是否存在其原型对象,如果程序中不存在,就创建一个,如果环境中存在,侧查找他们的属性和方法,最后根据查找的结果返回一个原型对象,这个对象中的属性和方法总是优先使用默认原型中的属性和方法,也就是构造函数中定义的属性和方法。当当调用的方法或属性不存在于默认的原型中时,才使用定义在Person.prototype = {} 的属性和方法。
javascript是解释性的语言,语句都是顺序执行的,在第一段代码中,当我们使用 new 关键字创建新对象的时候,Person.prototype = {} 并没有执行,也就是说在当前的执行环境中找不到其中定义的方法和属性,而构造函数中没有该方法,所以出错。就像一个变量,给他赋值的时候程序没有执行将不能使用。在第二段中环境中已经存在该调用的方法,构造函数的原型对象已经创建完毕,所以可以得到结果。
再看下面的一段程序:
//////////////////////////////////////////////////////////////////////////
function Person(){}
/*===========================================================*/
var person = new Person();
Person.prototype.name = 'song';
/*===========================================================*/
//Person.prototype.sayName = function(){alert(this.name)};
Person.prototype = {
constructor : Person,
name : 'zxs',
sayName : function(){alert(this.name)}
person.sayName(); // error
//////////////////////////////////////////////////////////////////////////
function Person(){
/*var person = new Person();*/
Person.prototype.name = 'song';
/*Person.prototype.sayName = function(){alert(this.name)};*/
Person.prototype = {
constructor : Person,
name : 'zxs',
sayName : function(){alert(this.name)}
/*===========================================================*/
var person = new Person();
/*===========================================================*/
person.sayName(); // zxs
从这里可以看出使用 Person.prototype.name = '',的方式不论在什么地方创建对象都能被访问,如果同时存在对象字面量和这种方法定义原型对象,将使用后定义的作为最终值。并且对原型对象使用对象字面量定义之后,该定义必须出现在创建对象的语句之前才能被访问到。
实例不能访问到原型对象中的属性和方法,不仅仅是因为重写原型对象切断了构造函数与最初原型之间的联系。
function Person(){
var person = new Person();
Person.prototype = {
//constructor : Person,
name : 'zxs',
sayName : function(){alert(this.name)}
person.sayName();
以上代码在实例化对象时构造函数的原型为空,它没有任何除默认属性以外的属性。重写构造函数的原型确实切断了构造函数与最初原型之间的联系。
在使用 new 操作符以后构造函数的原型对象中的属性和方法已经添加到 person对象中。因为以上方法为函数原型添加新属性和方法不具有动态性,所以person不能访问到新添加的属性和方法。
重写原型对象之后,就如同如下代码:
name : 'zxs'
console.log(o.name);
此时输出的值是undefined,因为,对象是一个引用类型,“=”是赋值操作符,并且其运算顺序是从右往左。o={}就是说o的指向已经改变,是一个空对象。
Person.prototype.mothed = function() {}与Person.prototype={mothed:function(){}}的区别就如同 arr = []和arr.push()一样,前者都是修改自身,后者是完全改变自身。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 举例说明对象和类 的文章

 

随机推荐