多态拓展性
可以理解为事物存在的多种体现形态
多态的基本体现
- 父类的引用可以指向自己的子类对象。
- 父类的引用也可以接受自己的子类对象。
多态的前提
- 必须是类与类之间有关系,要么继承,要么实现。
- 存在覆盖
多态的好处
- 提高拓展性
弊端
提高拓展性,但是只能使用父类的引用访问父类成员
多态的应用
多态转型
- animal a=new cat();//类型提升,向上转型在,子类向父类
- 强制将父类的引用,转成子类类型,向下转型
cat c=(cat) a;//将子类中引用的父类动物a强制转换猫c - 不可以创建父类对象,强制转换成子类
可以转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以强制转换。
*多态自始至终都是子类对象做着变化
animal a=new animal;
cat c=(cat) a;
instanceof
判断是否同一类型
判断子类与子类类型是否相同
多态成员函数的特点(非静态)
在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法
总结:成员函数在多态调用时,编译看左边,运行看右边。
无论编译和运行,都参考左边(引用型变量所属的类)
fu f=new zi();//若有同一变量打印fu
zi f=new zi();//若有同一变量打印zi
若是静态函数
在多态中,静态成员函数的特点:无论编译和运行,都看左边。
多态主板的示例
/*
类 主板,主板有运行方法run()
一段时间后想要上网 加入网卡类
想要听音乐 加入 声卡类
但是这样一个一个的加入使得代码的扩展性很差,每次都要重新修改很多代码
于是引入一个通用的接口PCI类
所有设备都有打开和关闭功能
让网卡和声卡分别取实现PCI接口,重写成自己的打开和关闭功能
给主板加上一个实现pcirun的方法,传递参数的值为PCI类型的
可以利用多态PCI p = new NetCard();
所以在下面主函数中运行时 创建新的主板对象以后
mb.pcirun(new NetCard());
mb.pcirun(new SoundCard());
就可以分别使用网卡和声卡了,如果以后还要再加入比如显卡
就只需要建立一个显卡类去实现PCI接口,然后直接用主板中的pcirun方法就可以了。
*/
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void pcirun(PCI p)
{
p.open();
p.close();
}
}
interface PCI
{
public abstract void open();
public abstract void close();
}
class NetCard implements PCI
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}
class SoundCard implements PCI
{
public void open()
{
System.out.println("SoundCard open");
}
public void close()
{
System.out.println("SoundCard close");
}
}
class Test
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
mb.pcirun(new NetCard());
mb.pcirun(new SoundCard());
}
}
/*
这样做的好处:
大大的降低了主板和各种独立设备直接的耦合性
中间用一个PCI接口来连接起来
程序日后非常方便扩展
*/
object
- Object类是类层次结构的根,Java中所有的类从根本上都继承自这个类。
- Object类是Java中唯一没有父类的类。
- 其他所有的类,包括标准容器类,比如数组,都继承了Object类中的方法。
是所有对象的直接后者间接父类,传说中的上帝
该类中定义的肯定是所有对象都具备的功能 - object类中已经提供了对对象是否相同的比较方法
如果自定义类中也有比较相同的功能,没有必要重新定义
只要沿袭父类中的功能,建立自己特有比较内容即可,这就是覆盖。
class demo
{
private int num;
demo(int num)
{
this.num=num;
}
public boolen equals(object obj)
{
demo d=(demo)obj;//向下转型,将obj降到使用子类的功能demo;
return this.num ==d.num;//使用到demo中的num,若没有向下转型,会报错num是没有引用的变量。
}
}
- equals(object obj) 比较地址值
- toString() 返回该对象的字符串
- Class来描述这些文件
Class 类1=类2.getclass();//得到类2所属类名