Java基础之多态

多态:在同一个时刻体现出来的不同状态;

        多态的前提:
   1) 必须有继承关系;
   子类继承父类,存在一些特点;
   2) 必须有方法重写;
   子类继承父类,方法重写的目的,举例:动物吃的方法,每一个具体动物吃的东西不一样,所有必须要方法覆盖;
   3) 就是必须有父类的引用指向子类对象 ==> (向上转型);
   父类名  fu = new  子类名( ) ;
                                        父类对象的创建是通过子类在堆内存新建了一个对象,由于子类又继承了父类,父类的引用(初始化)

                                 是通过子类新建对象进行的;

        多态中的成员访问特点:
   1)成员变量:             编译看左,运行看左;
   2)成员方法(非静态):   编译看左,运行看右(存在方法重写);

   3)构造方法:                构造方法(无论子类,还是父类),都是对对象进行初始化;

                4)静态成员方法:        编译看左,运行看左(静态跟类有关系,算不上方法重写);

        举例:

class Fu{
	int num = 20 ;
	public void show() {
		System.out.println("show Fu....");
	}
	public Fu(){
		
	}
	
	public static void function() {
		System.out.println("function Fu...");
	}
}
//子类
class Zi extends Fu{
	int num = 30 ;
	
	public void show() {
		System.out.println("show Zi....");
	}
	
	public static void function() {
		System.out.println("function Zi...");
	}
	
	public void method() {
		System.out.println("----4");
	}
}

//测试类
public class DuoTaiDemo {

	public static void main(String[] args) {
		//创建父类对象,通过子类创建对象
		Fu f = new Zi() ;        //向上转型;
		
		System.out.println(f.num);    //多态中访问成员变量:编译看父类,运行看父类 ==> 所以输出父类的成员变量num;
		f.show();                     //多态中访问成员方法(非静态):编译看父类,运行看子类 ==> 所以执行子类的show方法;
		f.function();     //多态中访问静态成员方法:编译看父类,运行看父类(静态跟类有关系,算不上方法重写);
		//f.method() ;    //会报错,因为多态的前提之一有方法重写,而method()这个方法没有方法重写,所以会报错;
	}
}
        多态的好处:
   可以提供代码的复用性:继承保证;
   可以提高的代码的扩展性:由多态保证 (父类的引用指向子类对象);
        多态的弊端:
父类引用指向子类对象,通过父类的引用调用子类特有功能,不能调用;

                例如:上面例题中的method()方法,父类 f 不能调用;

        问题:
                可不可以将子类的引用指向父类的引用呢?  (向下转型)
                解决方法:
                        将父类的引用强制转换成子类的引用;

//以上述代码举例:
    //创建父类对象,通过子类创建;
    Fu f = new Zi();    //向上转型;
    
    Zi z = (Zi) f;  //前提是必须有父类的引用,有了向上转型,才能创建向下转型;
    z.method();     //通过子类对象z访问method()方法;
        分层初始化:
                看程序,写结果:   爱你
//代码分析:
    //进入main方法,先通过类B创建类A的引用,接着访问父类的show()方法,执行其中的语句,根据多态中成员访问特点,访问成员方法,编译看父类,运行看子类;
    //所以会执行子类的show2()方法,执行其中的语句,输出==> 爱;
    //执行完,返回main方法,接着通过类C创建类B的引用,接着访问show()方法,因为类A,B,C形成了分层继承,所以在类B中隐式的存在类A方法名为show()的方法;
    //所以,访问类C中的show方法,执行其中的语句,接着访问类B中的show()方法,执行其中的语句;
    //在多态中访问成员的特点,访问成员方法,编译看父类,运行看子类,所以执行子类中的shoe2()方法,执行其中的语句,输出 ==> 你;
    //所以输出的结果为 :   爱你
class A {
	public void show() {
		show2();
	}
	public void show2() {
		System.out.print("我");
	}
}

class B extends A {
        /**
        * 解决问题的关键:类B继承了类A,所以会隐式的存在方法名为show()方法;
        * public void show(){
        *     show2() ;
        * }
        */

	public void show2() {
		System.out.print("爱"); //爱
	}
}

class C extends B {
	public void show() {
		super.show();
	}

	public void show2() {
		System.out.print("你");// 你
	}
}

public class DuoTaiTest {
	public static void main(String[] args) {
		A a = new B();
		a.show();		
		B b = new C();
		b.show();
	}
}

        两个面试题:

1、overload和override的区别?
        overload:方法重载
	    方法名一样,参数不同,和返回值没有关系
	        参数不同:
		    1)参数个数不同				
               	    2)参数类型不同
      override:方法重写 (子类定义一个和父类一摸一样的方法声明)	
            继续中使用到的	
		
2 关于this和super的区别?
        this:代表当前类的对象
	super:代表父类空间标识,理解为代表父类的对象	
	    应用场景:
		成员变量
        	    this.成员变量
		    super.成员变量
		成员方法
		    this.成员方法()
		    super.成员方法();					
		构造方法
		    this()/this("..")
		    super()/super("...");

阅读更多 登录后自动展开

扫码向博主提问

Future_LL

非学,无以致疑;非问,无以广识
去开通我的Chat快问
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页