Java面向对象的多态案例
矩形:横坐标、纵坐标、长度、宽度;
圆形:横坐标、纵坐标、半径;
写一个方法要求既能打印矩形又能打印圆形
图形父类:shape
public class Shape {
private int x;
private int y;
public Shape() {
super();
}
public Shape(int x, int y) {
super();
setX(x);
setY(y);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void show(){
System.out.println("(" + getX() + ", " + getY() + ")");
}
}
矩形子类:Rect 继承Shape父类
package xdl.day09;
public class Rect extends Shape {
private int len;
private int wid;
public Rect(){
}
public Rect(int x,int y,int len, int wid) {
super(x,y);
setLen(len);
setWid(wid);
}
public int getLen() {
return len;
}
public void setLen(int len) {
this.len = len;
}
public int getWid() {
return wid;
}
public void setWid(int wid) {
this.wid = wid;
}
@Override
public void show(){
super.show();
System.out.println("len = " + getLen() + ",wid = " + getWid());
}
}
圆形:Citcle继承父类Shape
public class Circle extends Shape {
private int r;
public Circle(){
super();
}
public Circle(int x, int y, int r) {
super(x, y);
setR(r);
}
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
//Override 改写父类的成员方法
@Override
public void show(){
super.show();
System.out.println("r = " + getR());
}
}
TestShape测试类
package xdl.day09;
public class TestShape {
//自定义成员方法来打印参数指定矩形的成员变量值
//Rect r = new Rect(1, 2, 3, 4);
public static void draw(Rect r){//static指分别指向各自类下的show方法
//调用Rect类型自己的show()方法
r.show();
}
//自定义成员方法来打印参数指定圆形的成员变量值
//Circle c = new Circle(5,6,7);
public static void draw(Circle c){
//调用Circle类自己的show()方法
c.show();
}
//自定义成员方法既能够打印矩形有能够打印圆形
//Shape s = new React(1,2,3,4); //父类的引用指向了子类的对象,形成了多态
//Shape s = new Circle(5,6,7); //父类的引用指向了子类的对象,形成了多态
public static void draw(Shape s){
//在编译阶段调用Shape类的show()方法,在运行阶段调用了子类重写的show()方法
//虽然看似调用同一个show方法,但是根据实参的不同最终调用不同的版本
s.show();
}
public static void main(String[] args){
//Rect r = new Rect(1,2,3,4);
TestShape.draw(new Rect(1, 2, 3, 4));
TestShape.draw(new Circle(5,6,7));
}
}
多态语法格式
父类类型 引用 = new 子类类型();
多态的效果
(1)对于指向子类对象的父类引用来说,在编译阶段只能直接调用父类的方法,
不能直接调用子类的方法;
(2)对于父子类都有的非静态方法来说,最终调用子类中的重写版本;
(3)对于父子类都有的静态方法来说,最终调用父类中的版本,与指向的对象类型无关;
引用类型之间的转换
(1)引用类型之间的转换必须发生在父子类之间,分为自动类型转换 和 强制类型转换;
(2)其中子类类型向父类类型的转换需要发生自动类型转换即可;
其中父类类型向子类类型的转换需要发生强制类型转换才可以;
(3)当没有父子类关系发生强转时则编译报错,当拥有父子类关系发生强转时则编译通过,
若目标类型并不是该引用真正指向的类型时,在运行阶段发生类型转换异常;
(4)为了避免上述错误的发生,通常只要进行强制类型转换就需要进行判断,格式如下:
if(引用变量名 instanceof 数据类型){ … }
- 判断引用指向的对象是否为指定的数据类型,若是则返回true,否则返回false;
多态的实际意义
多态的实际意义在于:可以屏蔽不同子类的差异性编写通用的代码,从而产生不同的效果