• 抽象类和接口


    一.抽象类

    1.基本概念

    如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,它的作用有点类似“模板”,其目的是根据它的格式来创建和修改新的类。

    语法:

     abstract class 抽象类名称 {
        // 抽象方法:被abstract修饰的方法,没有方法体
        abstract public void 方法名称();
    	// 抽象类也是类,也可以增加普通方法和属性  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注:抽象类内部可以包含普通方法和属性,以及构造方法。

    2.抽象类的特性

    1.抽象类不能直接实例化

    abstract class Animal {
       public abstract void bark();
    }
    public class Test {
        public static void main(String[] args) {
            Animal a = new Animal();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    编译出错:

    Animal是抽象的; 无法实例化

    2.抽象方法不能是private

    abstract class Animal {
        private abstract void bark();
    }
    
    • 1
    • 2
    • 3

    编译出错:
    非法的修饰符组合: abstract和private

    注:抽象方法没有加访问限定符时,默认是public

    3.因为抽象方法要被子类重写,所以不能被final和static修饰

    abstract class Animal {
        public abstract static void bark();
        public abstract final void eat();
    }
    
    • 1
    • 2
    • 3
    • 4

    编译出错:

    非法的修饰符组合: abstract和static
    非法的修饰符组合: abstract和final

    1. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰
    abstract class Animal {
        public abstract  void bark();
    }
    class Dog extends Animal{
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    编译出错:

    Dog不是抽象的, 并且未覆盖Animal中的抽象方法bark()

    1. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
    2. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量

    实现代码

    abstract class Animal {
        public abstract  void bark();
    }
    class Dog extends Animal{
    
        @Override
        public void bark() {
            System.out.println("汪汪.....");
        }
    }
    class Cat extends Animal{
    
        @Override
        public void bark() {
            System.out.println("喵喵.....");
        }
    }
    public class Test {
        //向上转型
        public static  void func(Animal a){
            a.bark();
        }
        public static void main(String[] args) {
        //多态的应用
          func(new Dog());
          func(new Cat());
        }
    }
    
    
    • 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

    输出结果:

    汪汪…
    喵喵…

    总结:

    1.抽象类最大的意义,是为了继承
    2.为了继承,抽象方法不能被staticprivatefinal修饰
    3.不能实例化抽象类

    二.接口

    1.接口的概念和定义

    在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型,它的结构与抽象类非常相似,具有数据成员、抽象方法、默认方法和静态方法,但它与抽象类有下列不同。
    (1)接口的数据成员都是静态的且必须初始化,即数据成员必须是静态常量。
    (2)接口中除了声明抽象方法外,还可以定义静态方法和默认方法。

    定义:

    在这里插入图片描述

    2.接口特性

    1.接口类型是一种引用类型,不能直接new接口对象

    interface IFlying{
         void Flying();
    }
    public class Test1 {
        public static void main(String[] args) {
             //Error:IFlying是抽象的; 无法实例化
            IFlying b = new IFlying();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)

    interface IFlying{
    //  Error:  此处不允许使用修饰符protected
        protected void Flying();
    }
    
    • 1
    • 2
    • 3
    • 4

    3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现

    interface IFlying{
    // Error:   接口抽象方法不能带有主体
          void Flying(){
              System.out.println("在天上飞");
          }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.重写接口中方法时,不能使用default访问权限修饰

    interface IFlying{
          void Flying();
    }
    class Duck implements IFlying{
    //Error:正在尝试分配更低的访问权限; 以前为public
        @Override
         void Flying() {
            System.out.println("天上飞");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final 变量

    interface IFlying{
        void Flying();
        String name = "大飞";//默认 public static final 修饰
    }
    
    • 1
    • 2
    • 3
    • 4
    1. 接口中不能有静态代码块和构造方法
    interface IFlying{
        void Flying();
        //编译失败
       public IFlying(){
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
    7. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
    8. jdk8中:接口中还可以包含default方法。

    实现案列:

    interface ISwimming{
        void swimming();
    }
    interface IRuning{
        void runing();
    }
    class Duck implements ISwimming,IRuning{
        public String name;
        public Duck(String name) {
            this.name = name;
        }
        @Override
        public void swimming() {
            System.out.println(this.name+"水里游");
        }
        @Override
        public void runing() {
            System.out.println(this.name+"地上跑");
        }
    }
    class Dog implements IRuning{
        public String name;
        public Dog(String name) {
            this.name = name;
        }
        @Override
        public void runing() {
            System.out.println(this.name+"水里游");
        }
    }
    public class Test1 {
        public static void func1(IRuning r){
            r.runing();
        }
        public static void func2(ISwimming s){
           s.swimming();
        }
        public static void main(String[] args) {
          func1(new Dog("大飞"));
          func1(new Duck("白糖"));
          func2(new Duck("白糖"));
        }
    
    }
    
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    输出结果

    大飞水里游
    白糖地上跑
    白糖水里游

    总结:

    1.接口不能被实例化
    2.当中的成员方法不能有具体的实现 ①抽象方法:默认是public static 的方法 ②JDK1.8开始,允许有可以实现的方法,只能有default修饰 ③可以实现一个静态的成员方法
    3.成员变量默认是public static final 来修饰
    4.子类重写抽象方法,必须加上public
    5.接口中不能有静态方法和构造方法

  • 相关阅读:
    Nlopt在matlab中的配置教程
    mysql8关闭binlog并清空Binlog
    Google vs IBM vs Microsoft: 哪个在线数据分析师证书最好
    JS之面向对象
    第04章 Tableau高级操作
    2022年12月英语六级预测范文—预测范文:Be Willing To Try
    抽丝剥茧,C#面向对象快速上手
    Java之Spring MVC中表单标签的简介说明
    CentOS防火墙管理及配置
    HarmonyOS开发实例:【分布式手写板】
  • 原文地址:https://blog.csdn.net/weixin_63993025/article/details/127134554