一个抽象类、接口、多态的简单实例。
News 和 UrlNews类
Displayable接口
1 2 3
| public interface Displayable { void display(); }
|
News类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class News implements Displayable{ // protected保证子类能继承访问 protected String title; protected String content;
// 父类缺省构造函数 public News(){}
// 构造的自由和责任交给用户 public News(String title, String content) { this.title = title; this.content = content; }
// title的getter接口 public String getTitle() { return title; } // content的getter接口 public String getContent() { return content; }
//注解表示方法来自上一层,可以检查方法名和方法类型是否写错了 @Override // 控制如何显示 public void display() { System.out.println(title + "\n" + content); } }
|
UrlNews类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class UrlNews extends News{ private String url;
// 缺省构造函数,默认调用super() public UrlNews() {}
// 含参构造函数 public UrlNews(String title, String content, String url) { super(title,content); this.url = url; }
// url的getter接口 public String getUrl() { return url; }
// 重写父类display()方法 @Override public void display() { System.out.println("News from Url:" + url); // 调用父类display() super.display(); } }
|
main实测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Main {
public static void main(String[] args) throws IOException { // 父类引用指向父类对象 News news = new News("abc","父类"); // 父类引用指向子类对象 News urlnews = new UrlNews("ABC","子类", "class.com"); // 父类display() news.display(); // 子类display() urlnews.display();
// 传入父类参数 viewNews(news); // 传入子类参数 viewNews(urlnews); }
// 传入实现Displayable接口的类(参数设为父类时,也可以传入子类参数) private static void viewNews(Displayable item) { item.display(); System.out.println("播放完毕"); } }
|
main测试结果
1 2 3 4
| abc 父类 News from Url:class.com ABC:子类
|
NewsReader 和 UrlNewsReader类
NewsReader类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public abstract class NewsReader {
// 抽象类中同样可以有成员变量 private Integer x;
// x的getter接口 public Integer getX() { return x; }
// x的setter接口 public void setX(Integer x) { this.x = x; }
// 抽象类方法,具有这个功能,但具体的功能实现,在子类中确定 public News readNews(String path) { System.out.println("来自父类"); //模拟读取 return null; } }
|
UrlNewsReader类
1 2 3 4 5 6 7 8 9
| public class UrlNewsReader extends NewsReader{
@Override public News readNews(String path){ super.readNews(path); System.out.println("Url reading......"); return null; } }
|
main实测
1 2 3 4 5 6
| ... News news2 = read(new UrlNewsReader(), "path_sample"); News news3 = read(new FileNewsReader(),"path_sample2"); NewsReader newsReader = new UrlNewsReader(); newsReader.readNews("path_sample"); ...
|
main测试结果
1 2 3 4 5 6
| 来自父类 // 父类NewsReader.display() Url reading...... // 子类UrlNewsReader.display() 来自父类 File reading... // 子类FileNewsReader.display() 来自父类 Url reading......
|
完整代码
Github
其中Content作为一个抽象类,表达得并不直接,会让用户不好理解,甚至可能觉得除了抽象方法外还有其他代码,而Content更趋向于表达一种功能,改为接口来表示会更符合实际应用场景。