------- 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培训、期待与您交流!----------