【java】多态


多态

对象既可以作为它自己本身的类型使用,也可以作为它的基类型使用

在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种特征
即:Music . tune() 方法接受一个Instrment 引用,同时也接受任何导出自Instrument的类,当然本身Music是子类,导出自Instrument类。

方法调用绑定
将一个方法调用同一个方法主体关联起来被称作绑定
包括:前期绑定 和 后期绑定(运行时根据对象的类型进行绑定,也成为动态绑定和运行时绑定)
Java中除了static方法和final方法(private方法属于final方法)之外,其他的所有方法都是后期绑定
声明final,可以“关闭”动态绑定,但是运用final要慎重。

产生正确的行为(向上转型)
package source.sunday;
import java.util.Random;
class Shape {
	public void draw() {}
	public void erase() {}
}
class Circle extends Shape {
	public void draw() { System.out.println("Circle.draw()"); }
	public void erase() { System.out.println("Circle.erase()"); }
}
class Square extends Shape {
	public void draw() { System.out.println("Square.draw()"); }
	public void erase() { System.out.println("Square.erase()"); }
}
class Triangle extends Shape {
	public void draw() { System.out.println("Triangle.draw()"); }
	public void erase() { System.out.println("Triangle.erase()"); }
}
class RandomShapeGenerator {
	private Random rand = new Random();
	public Shape next() {
		switch(rand.nextInt(3)) {
		case 0: return new Circle();
		case 1: return new Square();
		case 2: return new Triangle();
		}
		return null;
	}
}
public class Shapes {
	private static RandomShapeGenerator gen = new RandomShapeGenerator();
	public static void main(String[] args) {
		Shape[] s = new Shape[9];
		for(int i = 0; i < s.length; i++)
			s[i] = gen.next();
		for(Shape shp : s)
			shp.draw();
	}
}
RandomShapeGenerator类似一个工厂,通过随机方式生成shape对象。
output:


域和静态方法,不存在多态:
假如父类和子类拥有相同名字的域,那么会分配两个不同的空间。实际上这种情况基本不存在,因为你通常会将所有的域声明为private,因此不能够直接访问,其次,你可能不会对基类的域与导出类的域赋予相同的名字的。
任何的域访问操作都是由编译器解析,因此不是多态的,如果直接访问域(域是public的情况,本身就很少见),会返回基类的域值。

如果某个方法是静态的,因为静态的方法是类的属性,所以它就不具有多态性。
package source.sunday;
class StaticSuper {
	public static String staticGet() {
		return "Base staticGet";
	}
	public String dynamicGet() {
		return "Base dynamicGet";
	}
}
class StaticBub extends StaticSuper {
	public static String staticGet() {
		return "Derived staticGet";
	}
	public String dynamicGet() {
		return "Derived dynamicGet";
	}
}

public class StaticPolymorphism {
	public static void main(String[] args) {
		StaticSuper ss = new StaticBub();
		System.out.println(ss.staticGet());
		System.out.println(ss.dynamicGet());
	}
}
静态方法是与类,而并非与单个的对象相关联的。
output:


构造器的调用顺序:
1. 调用基类构造器。这个步骤会不断的反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,等等,直到最底层的导出类。
2. 按声明顺序调用成员的初始化方法。
3. 调用导出类构造器的主体。
注:构造器并不具有多态性,构造器实际上是static方法,只不过该static声明是隐式的。

向下转型
package source.sunday;
class Useful {
	public void f() {}
	public void g() {}
}
class MoreUseful extends Useful {
	public void f() {}
	public void g() {}
	public void u() {}
	public void v()	{}
}

public class RTTI {
	public static void main(String[] args) {
		Useful[] x = {
				new Useful(),
				new MoreUseful()
		};
		x[0].f();
		x[1].g();
		
		((MoreUseful)x[1]).u();
		((MoreUseful)x[0]).u();	//error:会抛出异常!没有此方法。
	}
}
上述错误会抛出异常: java.lang.ClassCastException
Exception in thread "main" java.lang.ClassCastException: com.factory.action.Array cannot be cast to com.factory.action.ArrayExtend




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值