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


    引言:

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

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

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







  • 相关阅读:
    MVC项目发布IIS CSS无法加载
    加班理由总结
    查找SQL Server 自增ID值不连续记录
    MySQL按时间查找
    近期任务
    AngularJs使用过程中,在ng-repeat中使用track by
    Java保留字和关键字
    抽象类和接口的区别
    Java标识符
    Java方法重载
  • 原文地址:https://www.cnblogs.com/xiangyangzhu/p/4260833.html
Copyright © 2020-2023  润新知