大家都知道java中三大重要的面向对象编程特点——封装、继承、多态。
今天我来讲讲多态:
首先,直接上代码
Shape 类:
public class Shape {
String name;
public Shape(){}//最好都写一个空的构造器
public Shape(String name) {
this.name = name;
}
public void getLength() {}
public void getPerimeter() {}
//子类不需继承该方法(第一种)
public void print(Shape s) {
s.getLength();
s.getPerimeter();
}
}
class Circle extends Shape{
public static double pi = 3.14;
double r;
public Circle(String name, double r) {
super(name);
this.r = r;
}
public void getLength() {
System.out.println(name+"的周长是:"+2*pi*r);
}
public void getPerimeter() {
System.out.println(name+"的面积是:"+pi*r*r);
}
}
class Rectangle extends Shape{
double width;
double height;
public Rectangle(String name, double width, double height) {
super(name);
this.width = width;
this.height = height;
}
@Override
public void getLength() {
System.out.println(name+"的周长是:"+2*(width+height));
}
@Override
public void getPerimeter() {
// TODO Auto-generated method stub
System.out.println(name+"的面积是:"+width*height);
}
}
//打印类(第二种)
class Print{
public void print(Shape s){
s.getLength();
s.getPerimeter();
}
}
测试类:
public class ShapeTest {
public static void main(String[] args) {
//第一种:直接在父类写一个打印方法(这样父类的负担加重,不推荐)
System.out.println("直接写一个打印方法在父类(子类没有该方法):");
Shape s = new Shape();
s.print(new Circle("圆",5));
s.print(new Rectangle("矩形", 5, 5));
//第二种:单独写一个打印类(占用内存空间更多,不推荐)
System.out.println("单独写一个打印类:");
Print p = new Print();
p.print(new Circle("圆",5));
p.print(new Rectangle("矩形", 5, 5));
//第三种:直接在测试类写print方法(需要的具体实现方法在主类写,推荐)
System.out.println("在主类中写打印方法:");
print(new Circle("圆",5));
print(new Rectangle("矩形", 5, 5));
}
//print打印方法(第三种)
private static void print(Shape s) {
// TODO Auto-generated method stub
s.getLength();
s.getPerimeter();
}
}
对于已经有面向对象思想的程序员来说,可以很好的看懂以上代码,但是对于要进入面向对象的学习者来说,可能不是很好接受,但是我已经用最简单的例子,并且有三种理解方式,应该多看几遍都可以理解。
1、什么叫多态呢?
必须有继承关系或者实现关系,遵循——is-a规则:子类的每个对象也是超类的对象。(置换法则:出现超类对象的任何地方都可以用子类对象置换)
2、多态详解
(1)实例化的对象是多态的。(父类的引用变量指向了子类的对象,或者接口的引用变量指向了接口的实现类的对象)
(2)子类数组的引用可以转换为超类数组的引用,但要尽量避免这样的使用,所有的数组都要牢记创建的元素类型。
(3)访问同名的静态的成员方法时,调用的是父类的方法
(4)访问同名的非静态的成员方法时,调用的是子类的方法(子类没有重写父类的某个方法时调用父类的该方法)
(5)访问同名变量时调用的是父类的成员变量(无论是否静态)
(6)在多态的情况下不能访问子类特有的成员