java 多态

什么是多态?

将一个方法调用同一个方法主体关联起来叫做绑定。若在程序执行前进行绑定,叫做前期绑定。
多态也称作动态绑定、后期绑定或者运行时绑定。是指在运行时根据对象的类型进行绑定。多态是继数据抽象和继承之后的第三种基本特征。

多态的作用是什么?

多态的作用是消除类型之间的耦合关系。多态通过分离做什么和怎么做,从另一角度将接口和实现分离开来。多态带来很多成效:更快的程序开发过程、更好的代码组织、更好扩展的程序以及更容易的代码维护等。

实例如下:Text0520.java

enum Note{//向上转型:把对某个对象的引用当做对其基类型的引用。
	MIDDLE_C,C_SHARP,B_FLAT;
}
class Instrument{
	void play(Note n){System.out.println("Instrument.play()");}
}
class Wind extends Instrument{
	void play(Note n){System.out.println("Wind.play() "+n);}
}
class Music{
	static void tune(Instrument i){i.play(Note.MIDDLE_C);}
	public static void main(String[] args){
		Wind aWind=new Wind();
		tune(aWind);//tune()接受一个Instrument引用,也接受Instrument的任何导出类。
	}
}
public class Test0520{
	public static void main(String[] args){Music.main(args);}
}
import java.util.Random;//多态是指在运行时根据对象的类型进行绑定。因此静态方法不具有多态性。
class Shape{
	void draw(){}
	void erase(){}
}
class Circle extends Shape{
	void draw(){System.out.println("Circle.draw()");}
	void erase(){System.out.println("Circle.erase()");}
}
class Square extends Shape{
	void draw(){System.out.println("Square.draw()");}
	void erase(){System.out.println("Square.erase()");}
}
class Triangle extends Shape{
	void draw(){System.out.println("Triangle.draw()");}
	void erase(){System.out.println("Triangle.erase()");}
}
class RandomShape{
	private Random rand=new Random(47);
	Shape next(){
		switch(rand.nextInt(3)){
			default:
			case 0:return new Circle();
			case 1:return new Square();
			case 2:return new Triangle();
		}
	}
}
class Shapes{
	private static RandomShape rs=new RandomShape();
	public static void main(String[] args){
		Shape[] s=new Shape[5];
		for(int i=0;i<s.length;i++){
			s[i]=rs.next();
		}
		for(Shape shape:s){//在编译时,编译器不需要获得任何特殊信息就能正确调用
			shape.draw();//对draw()方法的调用都是通过动态绑定进行的。
		}
	}
}
public class Test0520{
	public static void main(String[] args){Shapes.main(args);}
}
enum Note{//多态使程序更好扩展,将改变的事物与不变的事物分离开来
	MIDDLE_C,C_SHARP,B_FLAT;
}
class Instrument{
	void play(Note n){System.out.println("Instrument.play() "+n);}
	String what(){return "Instrument";}
	void adjust(){System.out.println("Adjusting Instrument");}
}
class Wind extends Instrument{
	void play(Note n){System.out.println("Wind.play() "+n);}
	String what(){return "Wind";}
	void adjust(){System.out.println("Adjusting Wind");}
}
class Percussion extends Instrument{
	void play(Note n){System.out.println("Percussion.play() "+n);}
	String what(){return "Percussion";}
	void adjust(){System.out.println("Adjusting Percussion");}
}
class Brass extends Wind{
	void play(Note n){System.out.println("Brass.play() "+n);}
	void adjust(){System.out.println("Adjusting Brass");}
}
class WoodWind extends Wind{
	void play(Note n){System.out.println("WoodWind.play() "+n);}
	String what(){return "WoodWind";}
}
class Music{
	static void tune(Instrument i){//tune()方法不需要编译就能和所有新类新方法一起正确运行。
		i.play(Note.MIDDLE_C);
	}
	static void tuneAll(Instrument[] e){
		for(Instrument i:e){tune(i);}
	}
	public static void main(String[] args){
		Instrument[] ins={new Wind(),new Percussion(),new Brass(),new WoodWind()};
		tuneAll(ins);
	}
}
public class Test0520{
	public static void main(String[] args){Music.main(args);}
}
-------------------------------------------------------------
E:\java>java Test0520
Wind.play() MIDDLE_C
Percussion.play() MIDDLE_C
Brass.play() MIDDLE_C
WoodWind.play() MIDDLE_C
class Meal{//继承与构造器的初始化
	Meal(){System.out.println("Meal()");}
}
class Bread{
	Bread(){System.out.println("Bread()");}
}
class Lunch extends Meal{
	Lunch(){System.out.println("Lunch()");}
}
class PortableLunch extends Lunch{
	PortableLunch(){System.out.println("PortableLunch()");}
}
class Sandwich extends PortableLunch{
	private Bread b=new Bread();
	public Sandwich(){System.out.println("Sandwich()");}
	public static void main(String[] args){
		new Sandwich();
	}
}
public class Test0520{
	public static void main(String[] args){Sandwich.main(args);}
}
-----------------------------------------------------------------------
E:\java>java Test0520
Meal()
Lunch()
PortableLunch()
Bread()
Sandwich()
class Glyph{//多态与构造器的初始化
	void draw(){System.out.println("Glyph.draw()");}
	Glyph(){//构造器准则:用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他(可以被覆盖的)方法。
		System.out.println("Glyph() before draw()");
		draw();
		System.out.println("Glyph() after draw()");
	}
}
class RoundGlyph extends Glyph{
	private int radius=1;//1.任何方法被调用之前进行默认初始化radius=0。//3.构造器调用之前自动初始化radius=1
	void draw(){System.out.println("RoundGlyph.draw(),radius = "+radius);}//2.调用覆盖方法
	RoundGlyph(int i){//4.调用构造器
		radius=i;
		System.out.println("RoundGlyph(),radius = "+radius);
	}
}
public class Test0520{
	public static void main(String[] args){
		new RoundGlyph(5);
	}
}
-------------------------------------------------
E:\java>java Test0520
Glyph() before draw()
RoundGlyph.draw(),radius = 0
Glyph() after draw()
RoundGlyph(),radius = 5
//协变返回类型:在导出类中进行覆盖的方法,可以返回基类被覆盖方法返回类型的某种导出类型
class Grain{public String toString(){return "Grain";}}//Grain基类

class Wheat extends Grain{public String toString(){return "Wheat";}}//Grain导出类

class Mill{Grain process(){return new Grain();}}//Mill基类返回Grain基类

class WheatMill extends Mill{Wheat process(){return new Wheat();}}//Mill导出类返回Grain基类的导出类型

public class Test0520{
	public static void main(String[] args){
		Mill m=new Mill();
		Grain g=m.process();
		System.out.println(g);
		m=new WheatMill();
		g=m.process();
		System.out.println(g);
	}
}
----------------------------------
E:\java>java Test0520
Grain
Wheat
class Actor{void act(){}}//继承设计准则:用继承表达行为间的差异,用字段(组合)表达状态上的变化。

class HappyActor extends Actor{
	void act(){System.out.println("HappyActor");}
}
class SadActor extends Actor{
	void act(){System.out.println("SadActor");}
}
class Stage{
	private Actor actor=new HappyActor();
	void change(){actor=new SadActor();}
	void performPlay(){actor.act();}
}
public class Test0520{
	public static void main(String[] args){
		Stage stage=new Stage();
		stage.performPlay();
		stage.change();
		stage.performPlay();
	}
}
---------------------------------------------
E:\java>java Test0520
HappyActor
SadActor
class Useful{//向下转型与运行时类型识别(RTTI)
	void f(){System.out.println("Useful.f()");}
	void g(){System.out.println("Useful.g()");}
}
class MoreUseful extends Useful{
	void f(){System.out.println("MoreUseful.f()");}
	void g(){System.out.println("MoreUseful.g()");}
	void h(){System.out.println("MoreUseful.h()");}
}
public class Test0520{//RTTI:在运行期间对类型进行检查的行为。
	public static void main(String[] args){
		Useful[] x={new Useful(),new MoreUseful()};
		x[0].f();
		x[1].g();//向上转型
		//向上转型会丢失具体的类型信息
		//x[1].h();//错误:Useful找不到方法h()
		//RTTI对类型进行检查,确保类型正确,否则返回异常
		((MoreUseful)x[1]).h();//向下转型成功,可以获取类型信息
		((MoreUseful)x[0]).h();//转型失败,返回一个ClassCastException类转型异常
	}
}
--------------------------------------------------
E:\java>java Test0520
Useful.f()
MoreUseful.g()
MoreUseful.h()
Exception in thread "main" java.lang.ClassCastException: Useful cannot be cast t
o MoreUseful
        at Test0520.main(Test0520.java:196)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值