黑马程序员技术交流社区
标题: java 多态(已解决) [打印本页]
作者: 王琪 时间: 2013-12-14 11:15
标题: java 多态(已解决)
本帖最后由 王琪 于 2013-12-22 02:04 编辑
<12>这个是我自己想的,想了很多样子,最后把自己弄混了!
谢谢
class person{
public String name="爸爸";
public int age=40;
public String talk(){
return "我是爸爸";
}
}
class student extends person{
public String name="孩子";
public int age=21;
public String school ="辽宁工大";
public String talk(){
return "我是儿子";
}
}
public class java {
public static void main(String[]args){
person p1_2;
student p2_2=new student();
p1_2=p2_2;
System.out.println(p1_2.name+p1_2.age+p1_2.talk());
System.out.println(p2_2.name+p2_2.age+p2_2.school+p2_2.talk());
/*
person p1_3;
student p2_3=new student();
p2_3=(student)p1_3;
person p1;
student p2=new student();
p1=p2;
p2=(student)p1;
System.out.println(p1_2.name+p1_2.age+p1_2.talk());
System.out.println(p2_2.name+p2_2.age+p2_2.school+p2_2.talk());
/*
//**********************************************************
person p3_2=new person();
student p4_2;
p4_2=(student)p3_2;
person p3_3=new person();
student p4_3;
p3_3=p4_3;
person p3=new person();
student p4;
p4=(student)p3;
p3=p4;
//**************************************************************
person p5_2=new student();
student p6_2=(student)p5_2;
p5_2=p6_2;
person p5=new student();
student p6=(student)p5;
p5=p6;
//*******************************************
//错student p7=new person();
person pp1=new person();
student pp2=new student();
pp1=pp2;
pp2=(student)pp1;
person pp1_2=new person();
student pp2_2=new student();
pp1_2=pp2_2;
person pp1_3=new person();
student pp2_3=new student();
pp2_3=(student)pp1_3;
*/
}
}
作者: 風諾 时间: 2013-12-14 11:26
问题是什么啊?
作者: 王琪 时间: 2013-12-14 11:42
父类的句柄操作子类,子类的句柄操作子类,不一样的?
子类产生子类的对象,但是子类型上转型成父类就是父类的指向该对象,这个对象丢失精度了吗?
person A=new student(),A是person的对象还是子类的对象?A执行的是父类的的方法吗?子对象强转成父类(person)A,(student)A呢?。。上面是我列的很多情况,每一个都说不通,
作者: 風諾 时间: 2013-12-14 12:07
Person p = new Student();父类引用,子类实例对象,以此为例:
1、该语句以后如果p调用了非静态方法,那么编译的时候会检查Person是不是具有该方法,运行的时候则会运行Student中的该方法。
如果调用了成员变量或者静态方法,无论编译或者运行,都是按照Person中的内容来的。
2、创建对象的时候,堆内存开辟空间,存入具体对象实例,之后你另一个引用类型指向该对象,只是把对象地址赋值给了该引用,没有改变对象内容。
3、p指向了子类对象。
4、1中说明了编译和运行的情况。
5、强制类型转换单独写没什么用,你肯定是要转换后赋值给某个类型的变量,那么又变成了1中的情况。
作者: 王松松 时间: 2013-12-14 12:12
- <P>public class Person
- {
- public String name = "Person";
- public int age = 20;
- public void talk()
- {
- System.out.println("我是Person");
- }
- public static void main(String[] args)
- {
- Person A = new Student();
- System.out.println("A:"+A.name+A.age);
- A.talk();
- System.out.println("..............");
- Student s = (Student)A;
- System.out.println("S:"+s.name+s.age);
- s.talk();
- }
- }
- class Student extends Person
- {
- public String name = "Stusent ";
- public int age = 10;
- public void talk()
- {
- System.out.println("我是Stusent ");
- }
- }
- //运行结果</P>
- <P>/*
- A:Person20
- 我是Stusent
- .............
- S:Stusent 10
- 我是Stusent</P>
- <P>*/
- </P>
复制代码
1,Person A=new student(), 这是父类引用指向子类对象,向上转型。
那么 A引用调用方法参阅的是A类,执行的是子类对象中的方法。
2,Student s = (Student) A ; 这是将指向子类对象的A类引用强转为子类型,向下转型。
那么s就是Student类型,调用方法参阅的是Student,执行的是Student类中的方法
作者: 王琪 时间: 2013-12-14 13:17
我听冯佳老师讲公开课时说,对于方法,编译看左边,执行看右边,就是父类会执行子类的覆写方法吧,
但是属性则是是调用就执行谁的?对吧!
谢谢你们!
作者: 王琪 时间: 2013-12-14 13:35
本帖最后由 王琪 于 2013-12-14 13:39 编辑
public class java{
public static void main(String[]args){
person p1_2;
student p2_2=new student();
p1_2=p2_2;
System.out.println(p1_2.name+p1_2.age+p1_2.talk());
System.out.println(p2_2.name+p2_2.age+p2_2.school+p2_2.talk());
}
}
class person{
public String name="爸爸";
public int age=40;
public String talk(){
return "我是爸爸";
}
}
class student extends person{
public String name="孩子";
public int age=21;
public String school ="辽宁工大";
public String talk(){
return "我是儿子";
}
}
结果是
爸爸40我是儿子
孩子21辽工大我是儿子
问题出在哪?
作者: 高亮亮 时间: 2013-12-14 13:51
本帖最后由 高亮亮 于 2013-12-14 13:54 编辑
其实,我理解这个多态的时候,想的是模板来让自己理解.
父类引用指向子类对象.这个是多态最常见的表现形式,你可以这么想.父类,子类,都是一个模具.成员变量,就像是可在模具上的信息,成员方法就像是模具上各种大大小小的凹槽,用来填充料.
当生成一个父类引用,就是生成了一个父类的模具;此时如果指向一个子类对象,就是用子类的模具先做一个产品出来,然后再放到父类上塞进去.这个时候,因为子类是继承父类的,父类的凹槽子类中肯定全有,而子类中还可能会多出更多凹槽,所以在子类产品塞上父类的模具的时候,对于那些子,父类都有的凹槽,子类产品是能塞进去的.没有的就只能暂且留在模具外面.而成员变量,就是文字,这样,拿的谁的模具,文字就是谁的.这样就是完整的解释了:父类引用,指向子类对象了.
而在这个情况下,想调用子类特有的功能,就需要进行向下转型.你想,我们本来就是用子类模具做出来的产品,虽然在塞到父类模具中是,那些子类特有凹槽做出来的部分暂且留在父类模具外面,但是如果这个时候我们再把它塞回子类模具,怎么样,是不是就又全能塞进去了.这就是向下转型,能够使用子类特有方法了.
上面是我自己想的辅助自己理解的.希望帮到楼主
作者: 王琪 时间: 2013-12-14 14:00
谢谢您,我好像明白了,我已开始以为向上转型以后,就把数据丢失了呢,原来是留在外边,那么就是说对象的转换和 一般变量的转换是不同的了,
不知该怎么谢谢大家!
作者: 高亮亮 时间: 2013-12-14 14:00
顺便再说一句,关于不同子类.就像是,子类们除了父类共同的凹槽外,其他凹槽大小,形状有差别.这个时候如果在子类与子类之间来进行转型,就像是把位置部件大小都有差别的产品部件硬塞,当然是不行的,所以这个时候转型是不合理的.
作者: 高亮亮 时间: 2013-12-14 14:02
是不太一样.我刚开始也以为一样.因为他们一个是引用类型,一个是基本数据类型,说的深了好像关系到自动拆箱,自动装箱什么的.先这么理解吧,可能以后会推翻现在想的,不过那样不是更好么,懂的更深了,呵呵~
作者: 王琪 时间: 2013-12-18 12:43
谢谢大家的帮助>.<
作者: 75100313 时间: 2013-12-18 15:18
三个条件 继承 重写 父类的引用指向子类的对象
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |