A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 Fozei 于 2015-8-25 18:09 编辑

本人小白,以前也不是从事IT工作的,最近自学Java基础,准备走流程进黑马培训班。新人,懂得少,有的时候学着学着有种蒙圈的感觉,提出一些问题可能会让行家笑掉大牙,但是也请见谅了,知之为知之,不知为不知吗,请看下面代码,是看毕老师视频后模仿的:
  1. package parctise;
  2. public class Demo {

  3.         public static void main(String[] args) {
  4.                
  5.                 //function(new pig());
  6.                
  7.                 pig p=new pig();
  8.                 function(p);               

  9.         }
  10.         //定义一个function函数供主函数调用,参数是Animal类型的c
  11.         private static void function(Animal c) {
  12.                 // TODO 自动生成的方法存根
  13.                 //判断传进来的函数属于哪种类型,并决定执行哪个动作
  14.                 if (c instanceof cat){
  15.                         c.eat();
  16.                         cat a=(cat)c;
  17.                         a.catchMouse();
  18.                 }
  19.                 else if (c instanceof pig){
  20.                         c.eat();
  21.                         pig a=(pig)c;
  22.                         a.gongDi();
  23.                 }
  24.                 else if (c instanceof dog ){
  25.                         c.eat();
  26.                         dog a=(dog)c;
  27.                         a.watchHome();
  28.                 }
  29.                
  30.                
  31.         }

  32. }
  33. //定义一个抽象类Animal
  34. abstract class Animal {
  35.         
  36.         abstract void eat();
  37. }
  38. //定义一个cat类,继承Animal
  39. class cat extends Animal{
  40.         void eat(){
  41.                 System.out.println("吃鱼");
  42.         }
  43.         void catchMouse(){
  44.                 System.out.println("抓老鼠");
  45.         }
  46. }
  47. //定义一个pig继承Animal
  48. class pig extends Animal{
  49.         void eat(){
  50.                 System.out.println("吃饲料");
  51.         }
  52.         void gongDi(){
  53.                 System.out.println("拱地");
  54.         }
  55. }
  56. //定义一个dog继承Animal
  57. class dog extends Animal{
  58.         void eat(){
  59.                 System.out.println("吃骨头");
  60.         }
  61.         void watchHome(){
  62.                 System.out.println("看家");
  63.         }
  64. }
复制代码

我的疑问出现在两种实现对象的方法上。在这个程序里,实现对象有两种方法:第一种,第6行的简略方法(我自己瞎说的),和第二种第8/9行的完全方法(也是我瞎说的)。其中第二种方法很好理解,function();运行,需要接收一个Animal类型的形参c,而在第八九行的语句里,新建了一个Animal的对象cat();,并且把他在内存中的地址值赋给了p,因此传给函数function的参数就是p指向的地址值,这个过程中,有一个把新建立对象的地址值赋给p,p在传递给c的过程。而在第一种方法中,却省略了对象在内存中地址值赋给p这个中间传送变量的过程,那么这个省略,是不是就相当于出现了一个对象,只有地址值,却没有名字的事实?好像他是隐形的?好疑惑呀,谁来给讲讲。

6 个回复

倒序浏览
怎么没人回答?自己回一个,防止沉底。
回复 使用道具 举报
学到多态了吧?
                function(new pig()); //这种方式叫做匿名调用 就是对象只需要调用一次的时候 可以用这种方法
                //堆中存放具体数据  栈中存放你所命名的变量名字
              // 既然叫匿名  自然没有名字  所以这就是在堆里有具体数据  而栈中没有名字指向这个数据的意思
              
                pig p=new pig();//这个的话就是实例对象了 在栈内存中有名字 同时在堆内存中有数据
                function(p);   

回复 使用道具 举报
至尊幽蓝 来自手机 中级黑马 2015-8-26 11:46:32
板凳
你得明白,new pig() 返回的就是一个对象的引用值,把它直接放在函数的参数位置用的是这个引用值,把它赋给该类型的一个引用(Pig pig=new pig();),再把那个引用放在函数参数或是什么地方,用的也是这个引用值,只不过这种匿名的方式只能用一次,再用时(又写一次new pig())就是又建立了一个新对象,而非匿名方式赋值过的pig就可以用无数次,只要不指向别处或置null。
回复 使用道具 举报
pengbeilin 发表于 2015-8-26 11:23
学到多态了吧?
                function(new pig()); //这种方式叫做匿名调用 就是对象只需要调用一次的 ...

非常专业,今天正好看了匿名内部类,发现有匿名调用存在的,现在豁然开朗了,非常感谢!
回复 使用道具 举报
至尊幽蓝 发表于 2015-8-26 11:46
你得明白,new pig() 返回的就是一个对象的引用值,把它直接放在函数的参数位置用的是这个引用值,把它赋给 ...

嗯,说的对,其实就是匿名调用,在只需要对对象进行一次调用的时候用这个方法,毕老师视频里肯定也提到来着,当时正走神呢,或者没理解到位,非常感谢回答。
回复 使用道具 举报
Fozei 发表于 2015-8-26 12:07
非常专业,今天正好看了匿名内部类,发现有匿名调用存在的,现在豁然开朗了,非常感谢! ...

没看到你提问之前,我也没意识到这个问题的存在,new一个匿名对象 在内存中是什么样子的,看到你的提问我才去百度搜索了,原来是这么一回事。相互学习!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马