JAVA多态

概念

多态主要指同一种事物表现出来的多种形态。如:
• 饮料:可乐、雪碧、红牛、脉动、...
• 宠物:猫、狗、鸟、小强、鱼、...
• 人:学生、教师、工人、保安、...

• 图形:矩形、圆形、梯形、三角形、...

语法格式

父类类型 引用变量名 = new 子类类型(); 如:

Shape sr = new Rect();

sr.show();

特点

1.当父类类型的引用指向子类类型的对象时,父类类型的引用可以直接调 用父类独有的方法。

2.当父类类型的引用指向子类类型的对象时,父类类型的引用不可以直接 调用子类独有的方法。

3.对于父子类都有的非静态方法来说,编译阶段调用父类版本,运行阶段 调用子类重写的版本(动态绑定)。

4.对于父子类都有的静态方法来说,编译和运行阶段都调用父类版本。

demo code:

public class Shape {
private int x;
private int y;

public Shape() {
}

public Shape(int x, int y) {
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());
}

// 自定义静态方法
public static void test() {
System.out.println("Shape类中的静态方法!");
}
}
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) {
        if(len > 0) {
            this.len = len;
        } else {
            System.out.println("长度不合理哦!!!");
        }
    }

    public int getWid() {
        return wid;
    }

    public void setWid(int wid) {
        if (wid > 0) {
            this.wid = wid;
        } else {
            System.out.println("宽度不合理哦!!!");
        }
    }

    @Override
    public void show() {
        super.show();
        System.out.println("长度是:" + getLen() + ",宽度是:" + getWid());
    }

    // 自定义静态方法
    public static void test() {
        System.out.println("---Rect类中的静态方法!");
    }
}
public class ShapeRectTest {

    public static void main(String[] args) {
         Shape sr = new Rect(7, 8, 9, 10);
        // 当Rect类中没有重写show方法时,下面调用Shape类中的show方法
        // 当Rect类中重写show方法后,下面的代码在编译阶段调用Shape类的方法,在运行阶段调用Rect类中的show方法
        sr.show(); // 7 8 9 10

        System.out.println("1.当父类类型的引用指向子类类型的对象时,父类类型的引用可以直接调 用父类独有的方法。2.当父类类型的引用指向子类类型的对象时,父类类型的引用不可以直接 调用子类独有的方法。");
        int ia = sr.getX();
        System.out.println("获取到的横坐标是:" + ia); // 7 
        //sr.getLen();  //error  Shape类中找不到getLen方法,也就是还在Shape类中查找  
     // 使用父类类型的引用调用子类独有方法的方式
// 相当于从Shape类型到Rect类型的转换,也就是父类到子类的转换 大到小的转换 强制类型转换
int ib = ((Rect) sr).getLen();
System.out.println("获取到的长度是:" + ib); // 9

    // 希望将Shape类型强制转换为Circle类型,下面没有报错
// Circle c1 = (Circle)sr; // 编译ok,但运行阶段发生 ClassCastException类型转换异常,Rect类无Circle

  // 在强制类型转换之前应该使用instanceof进行类型的判断
  // 判断sr指向堆区内存中的对象是否为Circle类型,若是则返回true,否则返回false
  if(sr instanceof Circle) {
  System.out.println("可以放心地转换了!");
  Circle c1 = (Circle)sr;
   } else {
  System.out.println("强转有风险,操作需谨慎!");
  } 
  }
}
引用数据类型之间的转换
 1.引用数据类型之间的转换方式有两种:自动类型转换 和 强制类型转换。

2.自动类型转换主要指小类型向大类型的转换,也就是子类转为父类,也叫做向上转型。

3.强制类型转换主要指大类型向小类型的转换,也就是父类转为子类,也 叫做向下转型或显式类型转换。

4.引用数据类型之间的转换必须发生在父子类之间,否则编译报错。

5.若强转的目标类型并不是该引用真正指向的数据类型时则编译通过,运行阶段发生类型转换异常。

 6.为了避免上述错误的发生,应该在强转之前进行判断,格式如下: if(引用变量 instanceof 数据类型) 判断引用变量指向的对象是否为后面的数据类型

原文地址:https://www.cnblogs.com/goldenwangyi/p/15072038.html