多态的动态联便技术
public class Shape {
float area(){
return 0.0f;
}
}
public class Circle extends Shape{
float r;
public Circle(float r) {
this.r = r;
System.out.println("有参构造");
}
@Override
float area() {
return (float) (3.1*r*r);
}
}
public class Rectangle extends Shape{
float width,height;
Rectangle( float w,float h){
width = w;
height = h;
System.out.println("这个是有参构造,只不过省略了public");
}
@Override
float area() {
return height*width;
}
}
注意:
/**
* 重写是方法名相同情况下,与父类有着相同的方法签名才算重写
* 重写完,父类的与子类相同名的哪个方法就会在子类当中被隐藏
* 当子类对象调用方法时候,自然调用的是子类当中的方法,不是调用父类哪个方法
*/
public class Test {
static float returnArea(Shape shape){
float f = shape.area();
return f;
}
/**
* 面向对象有一个说法是,子类对象也是超类对象,但凡超类对象可以应用的地方,子类对象也可以适用
*/
public static void main(String[] args) {
Circle c = new Circle(2.2f);
Rectangle rectangle = new Rectangle(2.2f,3.3f);
System.out.println("园的面积:="+returnArea(c));
System.out.println("长方形的面积:="+returnArea(rectangle));
}
}
方法的名字、参数的个数和类型完全相同,超类的dance( )方法在子类中就被隐藏。
当子类对象调用方法dance()时,自然调用子类的dance()方法。超类方法在子类中隐藏称为重写,或置换。
当子类中定义的成员变量和**超类中的成员变量同名**时,超类的成员变量同样会在子类中被隐藏。
子类对成员变量的隐藏和方法的重写可以把超类的状态和行为改变为自身的状态和行为。对于子类对象,如果子类重写了超类的方法,则子类对象调用这个方法时,调用子类方法。
如果子类继承了超类的方法(未重写),则会调用超类方法。
1.多态性
面向对象语言规定,子类对象也是超类对象,凡超类对象可以应用的地方,子类对象也适用。
将子类对象交给原本处理超类对象的方法retumArea()时,方法returmArea( )也一样能正确工作。
这样,调用方法returmArea()时,可以提供Shape类的对象,也可提供Circle类对象,或Rectangle类对象。即程序分别用Circle类对象C和Rectangle类对象r调用方法returmArea()也能正确执行。
但是,给编译系统带来了一个新问题。因为方法retumArea() 在被调用之前,是不知道调用的参数对象具体是哪一种类型,
编译暂时不能利用参数s的类型是Shape,就推断代码sarea()是调用Shape类的求面积方法。
如是这样,就会产生错误结果。这种编译时暂不绑定调用哪个方法,
必须在运行时才绑定调用方法的技术称为动态联编。而代码根据在执行时实际对象的类型不同,调用同名的不同方法,是面向对象语言的一种多态性。
解决这种多态性必须采用动态联编技术。由于Jon语言采用动态联编技术,保证以下程序能得到希望的结果。
有人也将调用重载方法作为多态性:生之一。重载能由调用时提供的参数个数和参数的类型顺序,在编译时就能确定被调用的方法,这种多态性不需要动态联编技术的支持。