风子的咖啡屋

 

2006年3月19日

多态

  什么叫多态?我们先来谈谈继承。在面向对象的编程中,继承是一种常用的技术。假设有一个类Shap,Shap有两个方法,即draw()和erase()。Circle也是一种特殊Shap,所以只需要使用继承的方法,使用class CricleextendsShap语句就可以创建一个新类Circle。Circle类具有Shap类的全部特征,包括所有的方法。这里只介绍了继承,到底这和多态有什么关系,到底什么又叫多态呢?看下面的语句:
 class Shap {
 void draw(){
  System.out.println("Shap.draw()");
 }
 void erase(){
  System.out.println("Shap.erase()");
 }

 

}
class Circle extends Shap{
 void draw(){
  System.out.println("Circle.draw()");
 }
 void erase(){
  System.out.println("Circle.erase()");
 }
}

 

class Square extends Shap{
 void draw(){
  System.out.println("Square.draw()");
 }
 void erase(){
  System.out.println("Square.erase()");
 }
}

public class Picture{
 void add(Shap s){
  s.draw();
 }
 public static void main(String[] args) {
  Picture p=new Picture();
  Shap[] e={
    new Circle(),
    new Square()
  };
  for(int i=0;i<e.length;i++)
  p.add(e[i]);
 }
 
}
注意看上面加红色的语句,及void add(Shap s){s.draw();}这表示一个Picture类的一个方法要使用Shap类作为形式参数并调用该参数的draw()方法。我们在接下来的语句中看到,不管你的Shap类的子类是Circle还是Square,在传递给方法add()后,add()能自动判断是调用Circle的draw()方法还是Square的draw()方法。JAVA这种“后期绑定”的本领就叫做多态。可以看出,你不必专门为Circle类写一个add()方法,再为Square写一个add()方法,只需要为它们的基类写一个方法,剩下的编译器就能为你自动选择你想要调用的正确的方法。如果多态仅仅是一种“向上转型”的形式的话,我们得到的仅仅是节省了一点代码的话,也许我们不必要给予太多的关注,那多态到底有什么其它好处呢?在上面的例子中新加一个Line类,它也继承了Shap类,如下所示:
 class Shap {
 void draw(){
  System.out.println("Shap.draw()");
 }
 void erase(){
  System.out.println("Shap.erase()");
 }

 

}
class Circle extends Shap{
 void draw(){
  System.out.println("Circle.draw()");
 }
 void erase(){
  System.out.println("Circle.erase()");
 }
}

 

class Square extends Shap{
 void draw(){
  System.out.println("Square.draw()");
 }
 void erase(){
  System.out.println("Square.erase()");
 }
}

class Line extends Shap{
 void draw(){
  System.out.println("Line.draw()");
 }
 void erase(){
  System.out.println("Line.erase()");
 }
}

public class Picture{
 void add(Shap s){
  s.draw();
 }
 public static void main(String[] args) {
  Picture p=new Picture();
  Shap[] e={
    new Circle(),
    new Square(),
    new Line()
  };
  for(int i=0;i<e.length;i++)
  p.add(e[i]);
 }
 
}

可以看出add()方法根本不必要知道有新类的增加而继续正常工作。咋看,这只不过还是节省了几行代码的问题,你可以为每个子类都写一个add()方法,同样能解决问题。有新类的加入时再为这个新类写add()方法。这不仅仅是节省了几行代码,多敲几行代码并不会如何提高编码的效率。这是一个思想,你根本不用关心基类今天多了一个子类,明天又多了一个子类,不用担心的你的代码中,对于新加入的子类能否正常的运行,因为你直接与基类的接口进行通信,避免了复杂性。换句话说,你的代码具有很好的可扩展性,基类可以随时根据需要进行扩展而不用担心代码的运行问题。

posted @ 2006-03-21 08:32 风子 阅读(206) | 评论 (0)编辑 收藏

final关键字的用法

final关键字:
可以在三种情况下使用final,及final数据,final方法,final类
1.final数据。final修饰的数字表示一个永不改变的编译时常量,对这个常量定义时必须对其进行赋值,可以在构造器中对其进行赋值(这种方法又叫空白final)。
用final加static修饰的字段只占据一段不可改变的存储空间。
2.final方法。final方法是把方法锁定,确保在继承中该方法行为保持不变,并且不会被覆盖。
3.fianl类。final修饰的类不能有继承类。

posted @ 2006-03-19 23:25 风子 阅读(250) | 评论 (0)编辑 收藏

导航

统计

常用链接

留言簿(1)

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜