多态——让学习的时候发疯的现象

引言:

本来想在继承那一博文中把多态写完的,但随着继承篇幅的增大,再加上多态这个让人看上去很厌烦、很复杂的问题,会是整个篇幅变得可读性极差,故灵气此文。

多态,作为面向对象三大特性之一,想必是让大家都很发疯的一项技术,作为学生,考试这里面基本上考倒一大部分人,子类父类的关系搞不清,结果更是出乎所料。本文详细阐述多态,望给大家提供些许启蒙。

多态:可以理解为事物存在的多种体现形态
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()); 


	}
}







posted @ 2015-01-28 19:15  YouxiBug  阅读(333)  评论(0编辑  收藏  举报