学习资源:拉勾教育
总的目录:拉勾教育 Java就业急训营 笔记目录
多态的概念和语法格式
- 多态主要指同一种事物表现出来的多种形态
父类类型 引用变量名 = new 子类类型();
多态的特点
- 当父类类型的引用指向子类类型的对象时,父类类型的引用可以
直接调用
父类独有的方法。 - 当父类类型的引用指向子类类型的对象时,父类类型的引用
不可以直接调用
子类独有的方法。 - 对于父子类都有的
非静态方法
来说,编译阶段调用父类版本,运行阶段调用子类重写的版本(动态绑定
)。 - 对于父子类都有的
静态方法
来说,编译和运行阶段都调用父类版本。
引用数据类型之间的转换
- 引用数据类型之间的转换方式有两种:
自动类型转换
和强制类型转换
。 - 自动类型转换主要指小类型向大类型的转换,也就是子类转为父类,也叫做
向上转型
。 - 强制类型转换主要指大类型向小类型的转换,也就是父类转为子类,也叫做
向下转型
或显式类型转换。 - 引用数据类型之间的转换必须发生在
父子类
之间,否则编译报错。
引用数据类型转换的注意事项
- 若强转的目标类型并不是该引用真正指向的数据类型时则编译通过,运行阶段发生类型转换异常。
- 为了避免上述错误的发生,应该在强转之前进行判断,格式为:
if(引用变量 instanceof 数据类型)
,判断引用变量指向的对象是否为后面的数据类型
多态的实际意义
- 多态的实际意义在于屏蔽不同子类的差异性实现通用的编程带来不同的效果。
案例题目
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());
}
// 自定义静态方法
//@Override error:历史原因、不是真正意义上的重写
public static void test() {
System.out.println("Rect类中的静态方法");
}
}
public class Circle extends Shape{
private int ir;
public Circle() {
}
public Circle(int x, int y, int ir) {
super(x, y);
setIr(ir);
}
public int getIr() {
return ir;
}
public void setIr(int ir) {
if(ir > 0) {
this.ir = ir;
} else {
System.out.println("半径不合理!");
}
}
@Override
public void show() {
super.show();
System.out.println("半径为:" + getIr());
}
}
public class ShapeRectTest {
public static void main(String[] args) {
// 1.声明Shape类型的引用并指向Shape类型的对象并打印特征
Shape s1 = new Shape(1, 2);
// 当Rect类中没有重写show方法时,下面调用Shape类中的show方法
// 当Rect类中重写show方法后,下面调用Shape类中的show方法
s1.show();
System.out.println("------------------------");
// 2.声明Rect类型的引用指向Rect类型的对象并打印特征
Rect r1 = new Rect(3,4,5,6);
// 当Rect类中没有重写show方法时,下面调用Shape类中的show方法
// 当Rect类中重写show方法后,下面调用Rect类中的show方法
r1.show();
System.out.println("------------------------");
// 3.声明Shape类型的引用指向Rect类型的对象并打印特征
// 相当于从Rect类型到Shape类型的转换 也就是子类到父类的转换 小到大的转换 自动类型转换
Shape sr = new Rect(7,8,9,10);
// 当Rect类中没有重写show方法时,下面调用Shape类中的show方法
// 当Rect类中重写show方法后,下面的代码在编译阶段调用Shape类中的show方法,在运行阶段调用Rect类中的show方法
sr.show();
System.out.println("------------------------");
// 4.测试Shape类型的引用能否直接调用父类和子类独有的方法呢???
int ia = sr.getX();
System.out.println("获取到的横坐标是:" + ia);
//sr.getLen(); error:Shape类中找不到getLen()方法,
// 调用静态方法
sr.test(); // 提示不建议使用引用.的方式访问
Shape.test(); // 提示使用类名.的方式访问
System.out.println("------------------------");
// 5.使用父类类型的引用调用子类持有的方式
// 相当于从Shape类型到Rect类型的转换 也就是父类到子类的转换 大到小的转换 强制类型转换
int ib = ((Rect) sr).getLen();
System.out.println("获取到的长度是:" + ib);
// 希望将Shape类型转换为Circle类型
//Circle c1 = new (Circle)sr; // 编译OK,但是运行阶段发生 ClassCastException类型转换异常
// 在强制类型转换之前应该使用instanceof进行类型的判断
// 判断sr指向堆区内存中的对象是否为Circle类型,若是则返回true,否则返回false
if(sr instanceof Circle) {
System.out.println("可以放心地转换!");
} else {
System.out.println("强转有风险,操作需谨慎!");
}
}
}
public class ShapeTest {
// // 自定义成员方法实现将参数指定矩形对象特征打印出来的行为,也就是绘制图形的行为
// public static void draw(Rect r) {
// r.show();
// }
//
// // 自定义成员方法实现将参数指定圆形对象特征打印出来的行为,也就是绘制图形的行为
// public static void draw(Circle c) {
// c.show();
// }
// 自定义成员放噶实现既能打印矩形对象又能打印圆形对象的特征,对象由参数传入
// 父类类型的引用指向子类类型的对象,形成了多态
// 多态的使用场合一:通过参数传递形成了多态
public static void draw(Shape s) {
// 编译阶段调用父类的版本,运行阶段调用子类重写以后的版本
s.show();
}
public static void main(String[] args) {
ShapeTest.draw(new Rect(1,2,3,4));
System.out.println("---------------------------");
ShapeTest.draw(new Circle(5,6,7));
}
}