zoukankan      html  css  js  c++  java
  • JAVA_SE基础——48.多态

    面向对象程序设计的三个特点是封装继承多态。前面已经学习了前两个特点。本章节将介绍多态性。


    多态:一个对象具备多种形态。(父类的引用类型变量指向了子类的对象)或者是接口 的引用类型变量指向了接口实现类的对象)


    多态的前提:必须存在继承或者实现 关系。


        动物  a  = new   狗();


    在多态中成员函数的特点:(针对非静态成员函数) 
     
        在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败 
     
        在运行时期,参阅对象所属的类中是否有调用的方法 
        简单总结就是:成员函数在多态中调用,编译看左边,运行看右边 
     
        在多态中,成员变量的特点: 
        无论编译还是运行,都参考左边(引用型变量所属的类) 
     
        在多态中,静态成员函数的特点: 
        无论编译还是运行,都参考左边 


    多态的好处: 提高了代码的拓展性。把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

    多态的应用一个对象具备了多种形态。 子类实现了父类后的对象,既是父类对象又是子类对象。

    具体应用:转型理解


    向上转型与向下转型的理解


    向上转型:父类 F =new 子类()


    向下转型:子类 Z=new (子类)F


    理解:


    1.子类实现了父类后的对象,既是父类对象又是子类对象。所以可以向下转换。这也就是多态的体现点,多种形态。就是会说这个既是父类对象又是子类对象的对象。


     2.向下转换后,就完全变成子类,可以调用子类的所有方法。  


    package day09;
    
    class Fu{
    	int num = 1;	//父类中的成员变量
    	
    	void method1(){
    		System.out.println("fu类中的method1()方法");
    	}
    	
    	void method2(){
    		System.out.println("fu类中的method2()方法");
    	}
    
    	static void method4(){
    		System.out.println("fu类中的method4()方法");
    	}
    }
    
    class Zi extends Fu{
    
    	int num = 2;
    	
    	void method1(){
    		System.out.println("Zi类中的method1()方法");
    	}
    
    	void method3(){
    		System.out.println("Zi类中的method3()方法");
    	}
    
    	static void method4(){
    		System.out.println("Zi类中的method4()方法");
    	}
    }
    
    
    class Demo9
    {
    	public static void main(String []args)
    	{
    		
    		Fu f = new Zi();
    		f.method1(); 
    		f.method2();
    		f.method4();	
    		System.out.println(f.num);//1
    		Zi z = new Zi();	
    		System.out.println(z.num);//2
    		z.method1();
    		z.method2();
    		z.method3();
    		z.method4();
    	}
    }

    运行结果:



    我自己对多态的理解(不喜勿喷):子类有的,就用子类的,子类没有的,就用父类的,子父类都没有的,报错。


    根据上面代码修改:在f.method4();  后面加句f.method3(); 

    package day09;
    
    class Fu{
    	int num = 1;	//父类中的成员变量
    	
    	void method1(){
    		System.out.println("fu类中的method1()方法");
    	}
    	
    	void method2(){
    		System.out.println("fu类中的method2()方法");
    	}
    
    	static void method4(){
    		System.out.println("fu类中的method4()方法");
    	}
    }
    
    class Zi extends Fu{
    
    	int num = 2;
    	
    	void method1(){
    		System.out.println("Zi类中的method1()方法");
    	}
    
    	void method3(){
    		System.out.println("Zi类中的method3()方法");
    	}
    
    	static void method4(){
    		System.out.println("Zi类中的method4()方法");
    	}
    }
    class Demo9
    {
    	public static void main(String []args)
    	{
    		
    		Fu f = new Zi();
    		f.method1(); //Zi类中的method1()方法
    		f.method2(); //fu类中的method2()方法
    		f.method4(); //fu类中的method4()方法
    		f.method3(); //这句是加上去的 
    		System.out.println(f.num);//1
    		Zi z = new Zi();	
    		System.out.println(z.num);//2
    		z.method1();
    		z.method2();
    		z.method3();
    		z.method4();
    	}
    }
    运行结果:


     

    引用:

     在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败 
     
     在运行时期,参阅对象所属的类中是否有调用的方法 
        简单总结就是:成员函数在多态中调用,编译看左边,运行看右边 

    ----------------------------------------------------------------------------------------------

     代码解释:f.method3();    .f   是所属Fu类的 ,,父类没有这方法    所以编译失败。


    如何理解这句话 :成员函数在多态中调用,编译看左边,运行看右边   

    意思就是:在编译的时候编译器不管你右边是什么类,只要左边的Fu类(或接口)能编译通过就不会报错。但是运行的时候就要按照右边的Zi()类实际情况来运行。

    当父类变量引用子类对象时(Fu fu = new Zi();),在这个引用变量 fu 指向的变量/方法中,他对成员变量和静态方法的调用与父类是一致的,他调用非静态方法时,在编译时是与父类一致的(查看父类有没有该函数,没有就会发生编译错误,提示fu 中找不到要调用函数),运行时如果子类中发生了复写就与子类一致。(如果右边没有再看左边。若都没有才会报错)


    那为何f.method3();     不能调用method3()方法呢 ?   

    如果想要调用Zi类的特有方法,如何操作?
                强制将父类的引用,转成子类类型。向下转型(怎么转看下面的code1 。)
    Zi x = (Zi)fu;
    x.method3();
     在多态中,调用子类函数,子类方法必须覆盖父类中的方法,如果调用子类特有的方法,就必须向下转型了。这样非静态的方法可直接调用。


    code1:

    package day09;
    
    class Fu{
    	int num = 1;	//父类中的成员变量
    	
    	void method1(){
    		System.out.println("fu类中的method1()方法");
    	}
    	
    	void method2(){
    		System.out.println("fu类中的method2()方法");
    	}
    
    	static void method4(){
    		System.out.println("fu类中的method4()方法");
    	}
    }
    
    class Zi extends Fu{
    
    	int num = 2;
    	
    	void method1(){
    		System.out.println("Zi类中的method1()方法");
    	}
    
    	void method3(){
    		System.out.println("Zi类中的method3()方法");
    	}
    
    	static void method4(){
    		System.out.println("Zi类中的method4()方法");
    	}
    }
    class Demo9
    {
    	public static void main(String []args)
    	{
    		
    		Fu f = new Zi();
    		f.method1(); //Zi类中的method1()方法
    		f.method2(); //fu类中的method2()方法
    		f.method4(); //fu类中的method4()方法
    		FuShout(f);
    		System.out.println(f.num);//1
    		Zi z = new Zi();	
    		System.out.println(z.num);//2
    		z.method1();
    		z.method2();
    		z.method3();
    		z.method4();
    	}
    	//定义一个向下转型的方法 。
    	public static void FuShout(Fu fu){
    		if(fu instanceof Fu){	//判断fu是否是Fu类的实例对象
    			Zi x = (Zi)			//将fu强转为Cat类型
    			x.method3();		//调用Zi类特有的method3()方法
    		}
    	}
    }


    运行结果:



    instanceof

    Java提供了一个关键字instanceof,它可以判断一个对象是否为某个类(或接口)的实例或者子类的实例。

    格式:

    对象(或者对象引用变量) instanceof 类(或接口)

  • 相关阅读:
    汇编指令(它不区分大小写)
    汇编
    LINUX命令
    LInux 终端命令
    回文串的Manacher算法
    hdu3336 Counting the string kmp的next数组的应用
    hdu2203kmp匹配
    hdu2087kmp模板练习
    hdu1171kmp果题
    hdu1686kmp果题
  • 原文地址:https://www.cnblogs.com/Jhaiha0/p/8465294.html
Copyright © 2011-2022 走看看