javaSE-chapter12多态性

1. 多态

    对象可以有多种形态,可以存在不同的形式。但多态是基于继承关系(父类和子类),也可以是实现关系(接口和实现类)。

    是将子类对象赋给父类变量,或用接口变量接收实现类对象,在运行时期表现出具体的子类或实现类特征。


2. 作用

    当把不同的子类对象当作父类类型来看待,可以屏蔽不同子类对象之间的差异,从而写出通用的代码达到通用编程,以适应需      求的不断变化。


3. 多态的常见情况

    SuperClass obj = new SubClass();  //SuperClass为SubClass的父类

  3.1 若某方法function()仅存在于父类中,不存在于子类中,调用obj.function(),则编译通过,调用的是父类的function()

  3.2 若方法function()存在于子类,不存在于父类中,调用obj.function(),则编译报错

  3.3 若方法function()存在于父类,也存在于子类中(即子类对该方法进行了复写),调用obj.function(),则编译通过,调用的是         子类中的function()

  3.4 若方法function()存在于父类,也存在于子类,但均为static方法,调用obj.function(),则编译通过,调用的是父类的               function()


4. 字段不存在多态特征

    在父类中声明某个可继承的成员变量,仅仅表示,子类具有访问的权限,但访问的都是同一块内存空间。若子类也声明了与父      类同名的成员变量,则在初始化的过程中,子类开辟了一个新的内存空间,用于存放自己的成员变量


5. 多态的原理

  5.1 绑定: 将一个方法调用同一个方法主体关联起来称为绑定。绑定分为前期绑定和后期绑定两种方式。

  5.2 前期绑定:在程序执行之前进行绑定(如果有的话,由编译器和连接程序实现)

  5.3 后期绑定:在运行时根据对象的实际类型进行绑定,也称为动态绑定和运行时绑定。

    java中除了static方法和final方法,private方法之外,都是后期绑定。这也就解释了3中的四种类型。如果方法不是static或者final(private)的,那么绑定是后期绑定,即在编译时(在编译期,只是确保调用方法的存在,并对调用参数和返回值执行类型检查),方法调用和方法体没有关联起来,只有到了运行时,根据引用所指向的对象类型,将方法调用和方法体关联起来。

class Fish {
	public static void play() { //static方法
		System.out.println("Fish.paly()");
	}
	
	final void eat() { //final方法
		System.out.println("Fish.eat()");
	}
	
	private void swim() { //private方法
		System.out.println("Fish.swim()");
	}
}

class GoldenFish extends Fish{
	public static void play() {
		System.out.println("GoldenFish.play()");
	}
	
	/*void eat() {
		System.out.println("GoldenFish.eat()");  --编译报错,不允许复写父类final方法
	}*/ 
	
	public void swim() {
		System.out.println("GoldenFish.swim()");
	}
}

public class Cooker {
	
	@Test
	public void test01() {
		Fish fish = new GoldenFish();
		fish.play(); --Fish.play()
		fish.eat(); --Fish.eat()
		//fish.swim(); --编译报错
	}
	
}

可参考:https://blog.csdn.net/zhongyili_sohu/article/details/8165043


6. 成员变量也不存在多态现象

首先看实例

public class Super {
	public int field = 0;
	public int getField() {
		return field;
	}
}

public class Sub extends Super{
	public int field = 1;
	public int getField() {
		return field;
	}
	public int getSuperField(){
		return super.field;
	}
}

public class FieldAccess {
	public static void main(String[] args) {
		Super sup = new Sub();
		System.out.println("super.field=" + sup.field); //该处访问的是父类的field字段   0
		System.out.println("super.genField()=" + sup.getField());   1
		
		Sub sub = new Sub();
		System.out.println("sub.filed=" + sub.field);  1
		System.out.println("sub.getField()=" + sub.getField());  1
		System.out.println("sub.getSuperField()=" + sub.getSuperField());  0
	}
}

解析: 

    当Sub对象向上转型为Super引用时,任何成员变量操作都由编译器解析,类似于前期绑定,不存在多态现象。

  在本例中,为Super.field和Sub.field分配了不同的存储空间。这样,sup实际上包含两个叫field的成员变量:它自己的和从父类继承的。如果声明的类型用的时Super类型,则访问的是父类super的field字段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值