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 表达实现⼀个接⼝, 从⽽声明这个类具有接⼝定义的属性
和⾏为
▸ 类可以实现多个接⼝! 例如表示: ⼀个⽂件即可以显示也可以打印

你可能感兴趣的:(Java 抽象类 接口 多态)