黑马成员_多态

------- android培训java培训、期待与您交流!----------

 

1 多态

 事物存在的多种体现形态

猫x=new 猫;    动物 x=new 猫;

 

2 注意:

在多态中成员函数的特点:

在编译时期,参阅引用型变量所属的类中,是否有调用的方法,如果有就编译通过,如果没有,就编译不通过

在运行时期,参阅对象所属的类中是否有调用的方法,如果有就编译通过,如果没有就编译不通过

 

/*
多态例子1:打印动物吃饭睡觉的方法
因为动物都有吃饭和睡觉的功能,但是他们吃什么和怎么睡都不能确定,所以把这些方法定义为抽象方法
这个类定义为抽象类,因为里面的方法都是抽象的,所以这个类是接口
 
我们以后要注意
接口的方法默认是抽象abstract和访问权限是public
*/

interface Animals
{
          void eat();
          void sleep();
}
 
//定义一个狗的类,实现Animals类,覆盖抽象方法
class Dog2 implementsAnimals
{
         public void eat()
         {
         System.out.println("狗吃骨头");
         }
 
         public void sleep()
         {
         System.out.println("狗晚上不睡觉");
         }
 
         //狗有看家的特殊本领
         void kanJia()
         {
         System.out.println("狗有看家本领");
         }
}
 
//定义一个猫的类,实现Animals类,覆盖抽象方法
class Cat2 implementsAnimals
{
         public void eat()
         {
         System.out.println("猫吃鱼");
         }
 
         public void sleep()
         {
         System.out.println("猫晚上睡觉");
         }
 
         //猫有抓老鼠的特殊本领
         void CatchMouse()
         {
         System.out.println("猫有抓老鼠本领");
         }
}
 
class DuoTaiDmeo
{       
         public static void main(String[] args)
         {
         Dog2 d=new Dog2();
         d.sleep();
 
         Cat2 c=new Cat2();
         c.sleep();
 
         //animals(d);
         }
 
         public static void animals(Animals obj)
         {
         obj.sleep();
         }
}

从上面可以看出猫和狗都有睡觉的方法,可是我们要分开调用,能不能更简便一点?

于是我们就定义一个方法,接收动物类型,方法里有sleep()方法,只要把动物传进来,就能睡觉了,太爽了吧

这个就是多态:父类引用指向了子类对象:Animals obj=new Dog2();     

obj是父类的引用指向了Dog2的对象,为什么obj.sleep()能调用狗的睡觉方法呢?

这是因为狗是动物的子类,并且复写了动物的睡觉方法

 

注意:我们父类引用不能调用子类的特有方法

obj.kanJan();这是错误的,因为父类中并没有这个方法,你却用父类的引用去调用它,编译的时候提示不认识这个方法!

 

但是我想把狗传进去调用kanJan()方法,怎么办呢?

强制转换类型!

先判断接受进来的对象是不是狗的本类对象

if(obj intancdof Dog2)

 

如果是狗的本类对象,那么把它强制转为狗的类型

Dog2 d=(Dog2)obj

记住下面几个总结

简单总结就是:成员函数在多态调用时,编译看左边,运行看右边

在多态中,成员变量的特点:

无论编译和运行,看的都是左边(引用型变量所属的类)

 

在多态中,静态成员变量和成员函数特点

无论编译和运行都参考左边(左边是属于那个类就参考那个类)

 

 

/*
多态例子2 :输出子父类的同名成员变量
*/
class Fu
{
         int num=5;
         void method_1()
         {
         System.out.print("fu method_1");
         }
         void method_2()
         {
         System.out.print("fu method_2");
         }
}
 
class Zi extends Fu
{
         int num=8;
         void method_1()
         {
         System.out.print("zi method_1");
         }
         void method_2()
         {
         System.out.print("zi method_2");
         }
}
 
class duoTai
{
         public static void main(String[] args)
         {
         Fu f=new Zi();  //这是多态父类引用指向子类对象
         System.out.print(f.num);//这里输出的是父类:5
 
         Zi z=new Zi(); //这是正常的创建对象的方法,本类引用指向本类对象
 
         System.out.print(z.num);//这里输出的是子类的:8
         }
}


/*
多态例子3:电脑运行实例,其中有涉及实现接口的代码
分析:电脑运行事实上是主板在运行,那么我们只要定义一个主板运行方法就行了,
         1)考虑到代码的复用性问题,我们可以把这个功能封装成一个类mainBoard  ,      
         我们知道主板都要运行和关闭功能吧
         所以定义run()和close()方法
 
         通过分析我们发现,主板上都有一个插槽,这个槽叫做PCI,网卡只要往上面一插就能随着主板运行了,
         但是市场上有那么多不同类型的网卡,有大的有小的,插不进去怎么办?
         不用急,世界计算机协会考虑到这个问题,统一规定生产网卡的厂商,所生产的网卡的规格都要符合PCI插槽,否则,就不用你的网卡
         2)所以我们为了遵循PCI的规则,就想到把PCI插槽定义为一个接口,让网卡去实现它的  
         定义一个接口    interface PCI    里面有打开和关闭的方法,让子类去实现它
 
         我们再想想主板运行了,没有其它组件的运行,也是没用
         3)所以,这时候我们要插一块网卡在主板上,
         定义一个网卡类    class netWork     
*/
//定义一个PCI接口,让子类去实现它,不能直接创建对象,子类要复写它里面的抽象方法
interface PCI
{
         public void open();
         public void close();
}
 
定义一个主板类
class mainBoard
{
         public void run()
         {
         System.out.print("运行");
         }
 
         //这里用到了多态,父类引用指向子类对象
         public void userPCI(PCI p)
         {
         p.open();
         p.close();
         }
}
 
//创建一个网卡类,实现PCI插槽,并覆盖里面的抽象方法
class netWork implementsPCI
{
         public void open()
         {
         System.out.print("网卡运行");
         }
         public void close()
         {
         System.out.print("网卡关闭");
         }
}
 
class duoTai2
{
         public static void main(String[] args)
         {
         mainBoard mb=new mainBoard();
         mb.userPCI(new netWork());
         }
}
 
/*
 模拟对象地址值的输出
 
equals比较的是地址值
 */
 
class demo   //定义一个demo类
{       
         private int num;  
         demo(int num)  //构造函数初始化
         {
         this.num=num;  //对num进行赋值
         }
         public boolean equals(Object obj) //定义一个equals比较功能
         {
         if(!(obj instanceof demo)) //判断0bj是否包含demo
                   return false;   
         demo de=(demo)obj;  //类型转换
         return this.num==de.num;
         }
}
 
class demoEquals2
{
         public static void main(String[] args)
         {
        
         demo d1=new demo(3);
         //demo d2=new demo();
         //System.out.print(d1.equals(d2));
        
         //拿到d1对象所属的类
         Class c=d1.getClass();
         System.out.println(c.getName()+"@"+Integer.toHexString(d1.hashCode()));
         System.out.print(d1.toString());
         }
}

 

------- android培训java培训、期待与您交流!---------- 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值