Java 抽象类 接口 多态

Java 多态

多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。

多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性

多态存在的三个必要条件

继承
重写
父类引用指向子类对象

比如:

Parent p = new Child();

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

多态的主要的实现⽅式

▸ 继承和接口
▸ ⽗类和接口类型的变量赋值⼦类对象
▸ 调⽤被override的⽅法

示例代码

以下是 Main.java

package com.company;

import com.company.model.*;


public class Main {

    public static void main(String[] args) {
        News news = new News("abc", "父类");
        FileNews fileNews = new FileNews("abc", "子类");
        Video video = new Video();


        // 以下这其实就是 多态 。。。。


        viewNews(news);  // implements 接口
        viewNews(video); // implements 接口
        viewNews(fileNews);  // extends 继承了父类 News 的 接口
        Displayable displayable = new Video();
        displayable.display();

        News new1 = read(new UrlNewsReader(), "path_sample");  //抽象类
        News new2 = read(new FileNewsReader(), "path_sample2"); //抽象类
        NewsReader newsReader = new UrlNewsReader(); //父类接口类型的变量赋值子类对象
        newsReader.readNews("path_simple"); //调用被 override 的方法


    }

    //使用 继承 抽象类 简化代码!!!
    private static News read(NewsReader reader, String path) {
        return reader.readNews(path);
    }

    /////////////////////////////////////////////////////////
//    private static News read(UrlNewsReader reader, String path) {
//        return reader.readNews(path);
//    }
//
//    private static News read(FileNewsReader reader, String path) {
//        return reader.readNews(path);
//    }
    ///////////////////////////////////////////////////////////////


    // 使用 接口 简化代码!!!
    private static void viewNews(Displayable item) {
        item.display();
        System.out.println("news播放完毕");
    }

    //////////////////////////////////////////////////////////
//    private static void viewVodeo(Video video) {
//        video.display();
//        System.out.println("video播放完毕");
//    }
//
//    private static void viewLecture(Lecture lecture) {
//        lecture.display();
//        System.out.println("lecture播放完毕");
//    }
    ///////////////////////////////////////////////////////////
}

抽象类为 NewsReader , FileNewsReader类 和 UrlNewsReader类 均继承于 NewsReader。

以下是 NewsReader.java

package com.company.model;

public abstract class NewsReader {


    private Integer x;


    public Integer getX() {
        return x;
    }

    public void setX(Integer x) {
        this.x = x;
    }

    public void test() {
    }


    public News readNews(String path) {
        System.out.println("来自父类");
        //模拟读取!!!
        return null;
    }

    ; //具有这个功能,但是具体的功能实现,在子类中确定!
}

以下是 FileNewsReader.java

package com.company.model;

public class FileNewsReader extends NewsReader {


    @Override
    public News readNews(String path) {
        super.readNews(path);
        //从文件读取,解析
        System.out.println("File reading ......");
        return null;
    }
}

以下是 UrlNewsReader.java

package com.company.model;

public class UrlNewsReader extends NewsReader {

    @Override
    public News readNews(String path) {
        super.readNews(path);
        //从网络读取,解析
        System.out.println("URL reading .........");
        return null;
    }
}

以下是 接口 Displayable.java

package com.company.model;

public interface Displayable {
    void display();
}

News 、 FileNews 、 Lecture 、 Video 均使用了 接口 Displayable
其中
public class FileNews extends News ,
public class News implements Displayable,
public class Lecture implements Displayable,
public class Video implements Displayable,

以下是 News.java

package com.company.model;

public class News implements Displayable {
    protected String title;
    protected String content;

    protected News() {

    }

    //构造的自由和责任交给用户!!
    public News(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }


    //控制如何显示
    @Override
    public void display() {
        System.out.println(title + "\n" + content);
    }
}

以下是 FileNews.java

package com.company.model;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class FileNews extends News {
    public FileNews(String title, String content) {
        super(title, content); //super 要和父类的构造方法一致
    }

    public FileNews() {
        super();
    }

    //子类 自己的 方法
    public void read(String url) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(new File(url)));
            title = reader.readLine(); //读取title
            reader.readLine(); //跳过空行
            content = reader.readLine(); //读取content
        } catch (java.io.IOException e) {
            System.out.println("新闻读取出错");
        }
    }

    //子类 重新实现 父类的 方法
    @Override
    public void display() {
        System.out.println(title + ":" + content);
    }
}

以下是 Lecture.java

package com.company.model;

public class Lecture implements Displayable {

    @Override
    public void display() {
        System.out.println("look a lecture");
    }
}

以下是 Video.java

package com.company.model;

public class Video implements Displayable {

    @Override
    public void display() {
        System.out.println("playing a movie");
    }
}

抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

以下为 抽象类 NewsReader.java

package com.company.model;

public abstract class NewsReader {


    private Integer x;


    public Integer getX() {
        return x;
    }

    public void setX(Integer x) {
        this.x = x;
    }

    public void test() {
    }


    public News readNews(String path) {
        System.out.println("来自父类");
        //模拟读取!!!
        return null;
    }

    ; //具有这个功能,但是具体的功能实现,在子类中确定!
}

继承抽象类 FileNewsReader.java 、 UrlNewsReader.java

package com.company.model;

public class FileNewsReader extends NewsReader {


    @Override
    public News readNews(String path) {
        super.readNews(path);
        //从文件读取,解析
        System.out.println("File reading ......");
        return null;
    }
}
package com.company.model;

public class UrlNewsReader extends NewsReader {

    @Override
    public News readNews(String path) {
        super.readNews(path);
        //从网络读取,解析
        System.out.println("URL reading .........");
        return null;
    }
}

抽象类总结

▸ ⽬的就是⽤于继承之后定义⼦类的类, 必然会⽤于定义⼦类
▸ 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员⽅法和
构造⽅法的访问⽅式和普通类⼀样
▸ 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使⽤
▸ 使⽤修饰符 abstract 声明⼀个类似抽象类, ⼀般具有抽象⽅法: abstract void
method(); 抽象⽅法只有声明, 没有实现
▸ ⼦类继承抽象类之后, 必须实现抽象⽅法, 不然仍然为抽象类, 可以override其他⽅法
▸ static⽅法不能声明为抽象⽅法
▸ is-a 关系!

接口

以下是 接口 Displayable.java

package com.company.model;

public interface Displayable {
    void display();
}

通过 implements 使用接口

package com.company.model;

public class News implements Displayable {
    protected String title;
    protected String content;

    protected News() {

    }

    //构造的自由和责任交给用户!!
    public News(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }


    //控制如何显示
    @Override
    public void display() {
        System.out.println(title + "\n" + content);
    }
}

因为public class FileNews extends Newspublic class News implements Displayable,所以FileNews也可以使用接口 Displayable

package com.company.model;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class FileNews extends News {
    public FileNews(String title, String content) {
        super(title, content); //super 要和父类的构造方法一致
    }

    public FileNews() {
        super();
    }

    //子类 自己的 方法
    public void read(String url) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(new File(url)));
            title = reader.readLine(); //读取title
            reader.readLine(); //跳过空行
            content = reader.readLine(); //读取content
        } catch (java.io.IOException e) {
            System.out.println("新闻读取出错");
        }
    }

    //子类 重新实现 父类的 方法
    @Override
    public void display() {
        System.out.println(title + ":" + content);
    }
}

接口小结

接⼝是⼀系列抽象⽅法 (但不需要abstract修饰, 隐式是public abstract)的集合
▸ 语义上表示具有⼀定的特性, ⽐如:
▸ ⾏⾛: 但是没有如何⾏⾛的定义
▸ 显示: 表示可以显示, 但是没有如何显示的定义
▸ 接⼝成员变量只能是 static final的. 因为它不是类, 不能实例化对象, 所以不会有状态,
只有属性
▸ 类通过关键字 implements 表达实现⼀个接⼝, 从⽽声明这个类具有接⼝定义的属性
和⾏为
▸ 类可以实现多个接⼝! 例如表示: ⼀个⽂件即可以显示也可以打印

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容