java中的多态性
多态性
(1)多态性定义
多态性:父类的引用指向子类的对象
(2)多态性的使用使用前提
①要有类的继承关系
②要有方法的重写
(3)多态性的使用(虚拟方法的调用)
有了对象的多态性以后,在编译时,只能调用父类中声明的方法。在运行时,实际执行的是子类重写父类的方法。在内存的加载中,实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时只能调用父类中声明的属性和方法,子类特有的属性和方法不能调用。
虚拟方法的调用
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的,只能在程序运行时才能确定,又称动态绑定。
(4)适用范围
对象的多态性只适合方法的调用,不适合属性的调用。在这里也印证了子类可以重写父类的同名同参数方法,但是不能重写同名属性。
①对于方法:在编译时,要查看引用变量所声明的类中是否有所调用的方法(父类中)。在运行时,调用实际new的对象所属的类中的重写方法(子类中)。即编译看左边,运行看右边。
②对于属性:不具备多态性,只看应用变量所声明的类。即编译和运行都看左边。
(5)实现多态的形式
在java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并重写接口中的同一方法)
举例:几何形状
定义三个类,父类GeometricObject代表几何形状(color:String,weight:double),子类Circle代表圆形(radius:double,finaArea():double),MyRectangle代表矩形(width:double,height:double,finaArea():double)。
定义一个测试类GeometricTest,编写equalsArea方法测试两个对象的面积是否相等,编写displayGeometricObject方法显示对象的面积。
创建父类GeometricObject
public class GeometricObject {
private String color;
private double weight;
//带形参构造器
public GeometricObject(String color,double weight){
super();
this.color = color;
this.weight = weight;
}
//抽象方法
public double findArea(){
return 0.0;
}
//get和set
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
创建子类Circle
public class Circle extends GeometricObject{//实现继承
private double radius;
//构造器
public Circle(double radius,String color,double weight){
super(color, weight);//super(形参)调用父类指定构造器
this.radius = radius;
}
@Override
public double findArea() {//父类方法重写
// TODO Auto-generated method stub
return Math.PI * radius * radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
创建子类MyRectangle
public class MyRectangle extends GeometricObject{//继承
private double width;
private double height;
//构造器
public MyRectangle(double width, double height,String color,double weight) {
super(color, weight);//super(形参)调用父类指定构造器
this.width = width;
this.height = height;
}
@Override
public double findArea() {//重写
// TODO Auto-generated method stub
return height * width;
}
//get和set
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
创建测试类GeometricTest
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
// boolean isEquals = test.equalsArea(new Circle(2, "红色", 2), new MyRectangle(3,4,"蓝色", 2));
// System.out.println(isEquals);
//
// test.displayGeometricObject(new Circle(2,"红色", 2));
// test.displayGeometricObject(new MyRectangle(3,4,"蓝色", 2));
Circle c1 = new Circle(3.2, "red", 1.0);
test.displayGeometricObject(c1);//多态使用
Circle c2 = new Circle(3.3, "red", 1.0);
test.displayGeometricObject(c2);
boolean isEqualsCircle = test.equalsArea(c1, c2);
System.out.println("c1和c2的面积是否相等:" + isEqualsCircle);
MyRectangle m1 = new MyRectangle(3.1, 4.5, "blue", 1.0);
test.displayGeometricObject(m1);
MyRectangle m2 = new MyRectangle(3.2, 6.5, "blue", 1.0);
test.displayGeometricObject(m2);
boolean isEqualsMyRectangle = test.equalsArea(m1, m2);
System.out.println("m1和m2的面积是否相等:" + isEqualsMyRectangle);
}
//测试两个对象的面积是否相等
public boolean equalsArea(GeometricObject o1,GeometricObject o2){//多态性的使用
//方式一:
// if(o1.findArea() == o2.findArea()){
// return true;
// }else{
// return false;
// }
//方式二:
return o1.findArea() == o2.findArea();//判断两个面积是否相等,返回值类型为boolean类型,若相等,则返回true,否则false。
}
//显示对象的面积
//多态性的体现,虚拟方法的使用
public void displayGeometricObject(GeometricObject area){//GeometricObject area = new Circle(...)
System.out.println("面积为" + area.findArea());
}
}
综上,上述例子很好的体现了面向对象中多态性的应用。
参考
https://www.bilibili.com/video/BV1Kb411W75Np=292&vd_source=e3d2dcdad07ba1c727f3c9e7654f60b5