引言:
本来想在继承那一博文中把多态写完的,但随着继承篇幅的增大,再加上多态这个让人看上去很厌烦、很复杂的问题,会是整个篇幅变得可读性极差,故灵气此文。
多态,作为面向对象三大特性之一,想必是让大家都很发疯的一项技术,作为学生,考试这里面基本上考倒一大部分人,子类父类的关系搞不清,结果更是出乎所料。本文详细阐述多态,望给大家提供些许启蒙。
多态:可以理解为事物存在的多种体现形态
1、多态的基本体现
父类的引用指向了自己的子类对象
父类的引用也可以接受自己的子类对象
2、多态的前提
必须是类与类之间有关系,要么继承,要么实现
通常还有一个前提,存在覆盖
3、多态的好处
多态的出现大大提高了程序的扩展性
4、多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类的成员
5、多态的应用
6、多态的出现代码中的特点(多态使用的注意对象)
空谈多态,太过抽象,简单说说执行结果,也不好理解,下面通过测试代码中的例子说明问题。
/*
动物
猫、狗
*/
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
public void eat()
{
System.out.println("chiyu");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("啃骨头");
}
public void kanJia()
{
System.out.println("看家");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
Animal a=new Cat(); //类型提升。向上转型。
a.eat();
//如果想要调用猫的特有方法时,如何操作?
//强制将父类的引用,转成子类类型. 向下转型
Cat c=(Cat) a;
c.catchMouse();
/*
但这种绝对不行 即将父类对象转成子类类型
我们能转的是父类的引用指向子类的对象时,该应用可以被提升,也可以被强制转换。
多态自始至终都是子类对象在变化
Animal a=new Animal();
Cat c=(Cat)a;
c.catchMouse();
*/
}
public static void function(Animal a)
{
a.eat();
if(a instanceof Cat)
{
Cat c =(Cat)a;
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog c =(Dog)a;
c.kanJia();
}
}
}
在多态中成员函数特点:
在编译时期引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败
在运行时期,参阅对象所属的类中是否有调用方法
简单总结就是成员函数在多态调用时,编译看左边,运行看右边
在多态中,成员变量的=特点:
无论是编译和运行,都是参考左边,(引用型变量所属的类)
在多态中,静态成员函数的特点:
无论编译还是运行都参考左边
abstract class Student
{
public abstract void study();
public void sleep()
{
System.out.println("躺着睡");
}
}
class BassStudent extends Student
{
public void study()
{
System.out.println("base study");
}
public void sleep()
{
System.out.println("坐着睡");
}
}
class advStudent extends Student
{
public void study()
{
System.out.println("adv study");
}
}
class DoStudent
{
public void doSth(Student stu)
{
stu.study();
stu.sleep();
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
DoStudent ds=new DoStudent();
ds.doSth(new BaseStudent());
ds.doSth(new advStudent());
/*
BaseStudent bs=new BaseStudent();
bs.study();
bs.sleep();
*/
}
}
需求:
电脑运行实例:
电脑运行基于主板
interface PCI
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void usePCI(PCI p)//接口型引用指向子类创建的对象
{
if(p!=null)
{
p.open();
p.close();
}
}
}
class NetCard implements PCI
{
public void open()
{
System.out.println("netcard open ");
}
public void close()
{
System.out.println("netcard close");
}
}
/*
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void useNetCard(NetCard c)
{
c.open();
c.close();
}
}
class NetCard
{
public void open()
{
System.out.println("netcard open ");
}
public void close()
{
System.out.println("netcard close");
}
}
*/
class DuoTaiDemo5
{
public static void main(String[] args)
{/*
MainBoard mb=new MainBoard();
mb.run();
mb.useNetCard(new Netcard());
*/
MainBoard mb=new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(Netcard());
}
}