一个多态的简单实例

2018-09-01  本文已影响0人  迷路的丸子

一个抽象类、接口、多态的简单实例。

News 和 UrlNews类

Displayable接口

public interface Displayable {
    void display();
}

News类

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类

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实测

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测试结果

abc
父类
News from Url:class.com
ABC:子类

NewsReader 和 UrlNewsReader类

NewsReader类

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类

public class UrlNewsReader extends NewsReader{

    @Override
    public News readNews(String path){
        super.readNews(path);
        System.out.println("Url reading......");
        return null;
    }
}

main实测

...
        News news2 = read(new UrlNewsReader(), "path_sample");
        News news3 = read(new FileNewsReader(),"path_sample2");
        NewsReader newsReader = new UrlNewsReader();
        newsReader.readNews("path_sample");
...

main测试结果

来自父类             // 父类NewsReader.display()
Url reading......   // 子类UrlNewsReader.display()
来自父类
File reading...     // 子类FileNewsReader.display()
来自父类
Url reading......

完整代码

Github

其中Content作为一个抽象类,表达得并不直接,会让用户不好理解,甚至可能觉得除了抽象方法外还有其他代码,而Content更趋向于表达一种功能,改为接口来表示会更符合实际应用场景。

上一篇下一篇

猜你喜欢

热点阅读