面向对象编程有三大特性:封装、继承、多态。
封装性就是尽可能的隐藏对象内部细节,对外形成一道边界,只保留有限的接口和方法与外界进行交互。封装的原则是使对象以外的部分不能随意的访问和操作对象的内部属性,从而避免了外界对对象内部属性的破坏。
继承它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展,它允许多种类对象视为它自己本身的类型或者其他类型处理。
多态指继承自同一个父类的不同子类根据方法行为的不同而进行区别,这些方法都可以通过同一个父类调用。
多态的实现
多态实现的三大要素:继承、重写、向上转型。
public class Shape {
public void draw() {}
public void erase() {}
}
public class Circle extends Shape {
public void draw() {
System.out.println("Circle draw()");
}
public void erase() {
System.out.println("Circle erase()");
}
}
public class Triangle extends Shape {
public void draw() {
System.out.println("Triangle draw()");
}
public void erase() {
System.out.println("Triangle erase()");
}
}
public class Square extends Shape {
public void draw() {
System.out.println("Square draw()");
}
public void erase() {
System.out.println("Square erase()");
}
}
public class RandomShapeGenerate {
private Random rand = new Random(47);
public Shape next() {
switch (rand.nextInt(3)) {
default:
case 0:
return new Circle();
case 1:
return new Square();
case 2:
return new Triangle();
}
}
}
public class Shapes {
private static RandomShapeGenerate gen = new RandomShapeGenerate();
public static void main(String[] args) {
Shape[] s = new Shape[9];
for (int i = 0; i < s.length; i++) {
s[i] = gen.next();
}
for (Shape shp : s) {
shp.draw();
}
}
}
输出:
Triangle draw()
Triangle draw()
Square draw()
Triangle draw()
Square draw()
Shape数组s 里面的对象引用是RandomShapeGenerate工厂随机产生的,在return时发生向上转型。
该例子中父类shape,子类Circle、Triangle、Square,子类重写了父类中的draw()、erase()方法,随机生成的子类全部赋值给Shape,因此满足了多态的全部条件。
多态的缺陷
只有普通的方法调用可以是多态的。
public class Super {
public int field = 0;
public int getField() {
return field;
}
public static void staticGet() {
System.out.println(" super static mthod");
}
}
public class Sub extends Super {
public int field = 1;
public int getField() {
return field;
}
public int getSuperField() {
return super.field;
}
public static void staticGet() {
System.out.println(" sub static mthod");
}
public static void main(String[] args) {
Super sup = new Sub();
System.out.println("sup.field = " + sup.field + " ,sup.getField() = " + sup.getField());
sup.staticGet();
Sub sub = new Sub();
System.out.println("sub.field = " + sub.field + " ,sub.getField() = " + sub.getField()
+ " ,sub.getSuperField()=" + sub.getSuperField());
}
}
输出:
sup.field = 0 ,sup.getField() = 1
super static mthod
sub.field = 1 ,sub.getField() = 1 ,sub.getSuperField()=0
小结:
1、任何域访问操作都由编译器解析,因此不是多态的。
2、如果某个方法是静态的,它的行为不具有多态性(静态方法是与类,而非与单个对象相关联的)。