你的位置:首页 > Java教程

[Java教程]【Java】子类的链式调用


记录最近在项目设计中遇到的一个小问题。

前提:有这样两个POJO类,它们都可以通过链式调用的方式来设置其属性值,其中一个类继承了另一个类。

问题:通过链式调用,子类对象访问父类方法后,如何使返回对象仍是子类对象,仍然可以继续链式调用子类的方法?

结论:子类重写父类中需要被调用的方法。在子类重写的方法中,首先通过super关键字调用父类方法,

        然后通过return this语句返回子类对象。

 

为了更具体、更形象的描述问题和解决办法,上示例代码。 

BaseOption、AppearanceOption 是两个实现了链式调用的POJO类,其中AppearanceOption 继承自BaseOption。

 1 package com.practice.option; 2  3 public class BaseOption { 4  5   private String id; 6  7   private String name; 8  9   public String getId() {10     return id;11   }12 13   public String getName() {14     return name;15   }16 17   public BaseOption setId(String id) {18     this.id = id;19     return this;20   }21 22   public BaseOption setName(String name) {23     this.name = name;24     return this;25   }26 27 }

View Code
 1 package com.practice.option; 2  3 public class AppearanceOption extends BaseOption { 4  5   private String color; 6  7   private String shape; 8  9   private String size;10 11   public String getColor() {12     return color;13   }14 15   public String getShape() {16     return shape;17   }18 19   public String getSize() {20     return size;21   }22 23   public AppearanceOption setColor(String color) {24     this.color = color;25     return this;26   }27 28   public AppearanceOption setShape(String shape) {29     this.shape = shape;30     return this;31   }32 33   public AppearanceOption setSize(String size) {34     this.size = size;35     return this;36   }37 38 }

View Code

此时,AppearanceOption 类的对象调用父类的方法后,返回的是父类对象。

如下图,setId()方法返回的是BaseOption对象,eclipse自动提示中看不到子类的方法。

 

修改子类AppearanceOption 的代码,重写父类方法。

 1 package com.practice.option; 2  3 public class AppearanceOption extends BaseOption { 4  5   private String color; 6  7   private String shape; 8  9   private String size;10 11   public String getColor() {12     return color;13   }14 15   public String getShape() {16     return shape;17   }18 19   public String getSize() {20     return size;21   }22 23   public AppearanceOption setColor(String color) {24     this.color = color;25     return this;26   }27 28   public AppearanceOption setShape(String shape) {29     this.shape = shape;30     return this;31   }32 33   public AppearanceOption setSize(String size) {34     this.size = size;35     return this;36   }37   38   @Override39   public AppearanceOption setId(String id) {40     super.setId(id);41     return this;42   }43 44   @Override45   public AppearanceOption setName(String name) {46     super.setName(name);47     return this;48   }49 50 }

View Code

现在setId()方法返回的是AppearanceOption 对象,eclipse自动提示中可以看到子类的方法了。

从结论来看,并没有用到多么高深的技术,主要还是对面向对象特征的理解和运用。可是,在实际设计代码结构的时候愣是半天没想到。

主要的解决思路是来自Java源码的启发。在Java中,最常见的链式调用就是 StringBuffer、StringBuilder 类中的 append() 方法。我们可以通过连续的.append().append()方法来完成字符串的拼接。如果稍微熟悉源码,可能会知道 StringBuffer、StringBuilder 这两个类都继承自抽象类AbstractStringBuilder,该抽象类中也有append() 方法。答案显而易见了,查看一下 StringBuffer 或者 StringBuilder 的源码就知道了。