栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java —— 抽象类、接口,你不知道的都在这里 ! !

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java —— 抽象类、接口,你不知道的都在这里 ! !

Java —— 抽象类、接口,你不知道的都在这里 ! !

每博一文案
在懂你的人面前,你可以卸下伪装,做最真实的自己,经历的事情越多,
就越发觉身边很少有人能懂你。因为懂得,所以默契,因为懂得,所以安心。
就像那句话说的,人生的每一场相遇,倘若不是幸运,那就是教训。
凡是错误的关系,都是费劲的关系。
大千世界里,每朵花都有每朵花的盛开。
衰败每个人都有,每个人的欢喜与落寞,而懂得永远比爱更慈悲。
请相信,在这个世间行走,遇见无数的人,唯有三观相合才可以一起走到最后。
                                            ——————————————    一禅心灵庙语

文章目录
  • Java —— 抽象类、接口,你不知道的都在这里 ! !
    • 每博一文案
    • 抽象类
    • 接口
    • 最后:


抽象类
  • 子类在继承父类的过程中,会继承父类的一些方法,如果不能确定子类类型到底该如何实现,可以先将父类中的方法定义为 抽象类 ,当子类继承时再进行具象化。
  • 抽象类的定义使用关键字 :abstract 格式如下:
abstract class Shapes {
    
}
  • 抽象方法 ,抽象方法是没有主体的,不可以加上 { } 的代码块,
  • 抽象方法是存在于抽象类里面的,只要包含一个抽象方法,该类就必须是抽象类
  • 抽象方法的定义 :格式如下:
  abstract void draw(); // 注意不可以有主体,抽象方法
  • 抽象类 是不可以被实例化的,会出错的
abstract class Shapes {

    abstract void draw();
}

public class Blog06 {
    public static void main(String[] args) {
        Shapes shapes = new Shapes();

    }
}

运行结果


  • 抽象类中可以有 普通的方法和字段
abstract class Shapes {
    protected String name;
    public void pint() {
        
    }
    abstract void draw();
}
  • 抽象类主要就是用来继承的,通过继承的方式,实例化子类,通过子类调用,重写的构造方法 向上转型
  • 如果一个类继承了,这个抽象类,那么这个类必须重写抽象类当中的所有抽象方法
  • 当抽象类 A 继承了抽象类 B ,那么 A 可以不用重写 B 抽象类中的抽象方法,因为 A自己也是抽象类,但是一旦继承的不是 抽象类,那么就一定需要重写该 继承中抽象类中的所有抽象方法
  • 注意 无论是 抽象类 还是 抽象方法 都不可以 被 final 修饰,因为被 final(最后,无法改变) 修饰的类是无法被继承了,final 修饰的抽象方法是无法被重写的,
  • 非抽象方法 可以调用 抽象方法的
final abstract class Shapes { // 抽象类不可以被 final 修饰无法被,继承的
    protected String name;
    public void pint() {

    }
    abstract void draw();
}

public class Blog06 {
    public static void main(String[] args) {


    }
}

运行错误结果


abstract class Shapes {
    protected String name;
    public void pint() {

    }
    abstract final  void draw(); // 抽象方法,不可以被 final 修饰,修饰了无法重写该抽象方法
}

class Circle extends Shapes {
    @Override // 重写,注解 错误提醒功能,人和编译器都可以读懂的注释
    public final void draw() {
        System.out.println("画一个 ");
    }
}

public class Blog06 {
    public static void main(String[] args) {


    }
}

运行错误结果


  • 抽象类实例:
abstract class Shapes {
    protected String name;
    public void pint() {

    }
    abstract  void draw(); // 抽象方法,不可以被 final 修饰,修饰了无法重写该抽象方法
}

class Circle extends Shapes {
    @Override // 重写,注解 错误提醒功能,人和编译器都可以读懂的注释
    public final void draw() {
        System.out.println("画一个 ");
    }
}

class Stars extends Shapes {
    @Override
    public final void draw() {
        System.out.println("画一个 ");
    }
}

public class Blog06 {
    public static void func(Shapes shapes) {
        shapes.draw();
    }
    public static void main(String[] args) {
        Shapes shapes = new Circle();
        Shapes shapes1 = new Stars();
        func(shapes);
        func(shapes1);

    }
}

运行结果:


  • 抽象类本身是不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类重写抽象类中的抽象方法
    • 有些人会有这样的想法:普通的类也是可以被继承呀,普通的方法也是可以被重写的,为啥子非得用这么复杂的抽象类和抽象方法呢
    • 确实如此,但是使用抽象类相当于多了一重编译器的校验,使用抽象类的场景就如同上面的实例代码一样,实际工作不应该由父类完成,而是应由子类完成,那么此时如果不小心误用父类了,使用普通类,编译器是不会报错的,但是父类是抽象类就会实例化的时候,就会提示错误,让我们尽早发现问题尽早处理问题
  • 事实上,很多语法存在的意义,都是为了预防出 “出错” ,例如我们长常用的 final 也是类似的,创建的变量用户不去修改,不就相当于是常量吗? 但是 加上了 final 能够在不小心修改的时候,让编译器及时提醒我们

接口
  • 接口和类是并列的关系,都属于引用数据类型的一种,类的定义使用关键字 class ,接口的定义使用关键字 interface 。接口用来定义一种能力,某个类型要具备接口提供的能力,就要实现这个接口。
  • 接口的定义:如下:
interface IFlying { // 接口的定义
    void fly(); // 抽象方法
}
  • 在 JDK1.8 之前,接口中只有两部分内容:

    1. 常量 :固定默认修饰符为 :public static final , 可以省略不写
    • 声明中带有 static 的类变量可以通过 **“类名.字段名” ** 进行访问,与此相同的,接口中的常量可以通过 “接口名.字段名” 进行访问
    1. 抽象方法 : 固定默认修饰符为:public abstract ,可以省略不写
  • 在 JDK1.8 之后,新增了如下非抽象方法:

    1. 被 public default 修饰的非抽象方法
    2. 静态方法
  • 接口是不可以实例化的,而是通过继承实现接口:

interface IFlying { // 接口的定义
    void fly(); // 抽象方法
}

public class Blog06 {
    public static void main(String[] args) {
        IFlying iFlying = new IFlying();
    }
}

错误运行结果


  • 接口和类之间的关系,implements(实现接口的意思) 因为接口中的方法是抽象方法,所以在实现上是要对抽象方法进行重写的
  • 注意 接口中的对重写的抽象方法 的 权限修饰符 必须是 public ,因为接口中的抽象方法默认是 public abstract 的,根据重写的规则:子类中的权限修饰符必须 **>= ** 父类中的权限修饰符,而 public 是最大的,所以我们只能用相等的 public 修饰了
  • 接口的实现使用关键字 :implements
  • 当类的声明中同时存在 extends(继承) 和 implements(接口的实现) 时,一定要先书写 extends(继承) ,再写 implements(接口的实现)
class Zoon {

}

interface IFlying { // 接口的定义
    void fly(); // 抽象方法
}

class Brids extends Zoon implements IFlying {
    @Override
    public void fly() { // 注意重写接口中的抽象方法 ,必须是 public 的权限修饰符,

    }
}
  • 为了解决 Java 中单继承的问题,可以实现多个接口,使用 逗号 分隔别个 接口 ,一个类实现了多个接口就需要重写 所有接口的 抽象方法
  • 只要这个类,实现了接口,那么你就可以进行 向上转型了
class Zoon {
    protected String name;
    public  Zoon(String name) {
        this.name = name;
    }
}


interface IRuning { // 接口的定义
    void run(); // 接口中的抽象类
}

interface ISwimming { // 接口的定义
    void swim(); // 接口中的抽象类
}

// 多个接口的实现,逗号分隔
class Frog extends Zoon implements IRuning,ISwimming { // IRuning,ISwimming 接口的实现
    public Frog(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println(super.name+" 可以跑的飞快");
    }
    
    @Override
    public void swim() {
        System.out.println(super.name+" 可以游得飞快");
    }
}


  • 我们通过接口类型的变量可以引用实现该接口的类类型的实例。只有实现了对应接口才可以调用 该接口中的抽象方法的重写
  • 多接口,接口的使用实例:
class Zoon {
    protected String name;
    public  Zoon(String name) {
        this.name = name;
    }
}

interface IFlying { // 接口的定义
    void fly(); // 抽象方法
}

interface IRuning { // 接口的定义
    void run(); // 接口中的抽象类
}

interface ISwimming { // 接口的定义
    void swim(); // 接口中的抽象类
}

class Brids extends Zoon implements IFlying { // 继承 IFlying接口的实现
    public  Brids(String name) {
        super(name); // 调用父类的构造方法,第一行
    }

    @Override
    public void fly() { // 注意重写接口中的抽象方法 ,必须是 public 的权限修饰符,
        System.out.println(super.name+ " 可以飞的飞快");
    }

}


class Fish extends Zoon implements ISwimming { // ISwimming 接口的实现
    public Fish(String name) {
        super(name);
    }

    @Override
    public void swim() {
        System.out.println(super.name+" 可以游的飞快");
    }
}

class Cats extends Zoon implements IRuning { // IRuning 接口的实现
    public Cats(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(super.name+" 可以跑的飞快");
    }
}

class Frog extends Zoon implements IRuning,ISwimming { // IRuning,ISwimming 接口的实现
    public Frog(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(super.name+" 可以跑的飞快");
    }

    @Override
    public void swim() {
        System.out.println(super.name+" 可以游得飞快");
    }
}


public class Blog06 {
    public static void main(String[] args) {
        IRuning iRuning = new Cats("年轻的猫"); // 定义 IRuning 接口类型,访问接口的抽象方法 run()
        iRuning.run();

        IFlying iFlying = new Brids("年轻的鸟");// 定义 IFlying 接口类型,访问接口的抽象方法 fly()
        iFlying.fly();

        Frog frog = new Frog("年轻的青蛙");// 实例化子类,访问子类中的方法
        frog.run();
        frog.swim();


    }

运行结果


  • 上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口.
  • 这样设计有什么好处呢? 时刻牢记 多态 的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力

最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵 —— 多多指教,谢谢大家,后会有期,江湖再见!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号