• java基础08


    一、抽象类

    介绍

    #

    使用场景

    在这里插入图片描述

    语法

    在这里插入图片描述

    抽象类的注意事项和细节(注意: 1,5,8)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    抽象类和普通类的区别

    • 不能被实例化,但可以作为父类引用指向子类对象
    • 修饰符不能有private,final,static
    • 如果有抽象方法抽象类一定要加上abstract
    • 继承过程中抽象方法一定要被实现或者继续抽象

    模板设计模式

    介绍

    把通用的步骤放到抽象类的一个执行方法中,每个步骤定义成抽象方法,子类实现每个步骤的细节,当子类调用父类的执行方法时,如果遇到通用步骤就会调用子类的具体步骤来实现,(注意:新建对象时运行类型和编译类型都是子类的,只是调用了父类的方法而已,而通用步骤的方法子类对父类已经实现,所以调用的还是子类的)

    案例

    在这里插入图片描述

    package com.bijing.static_.abstract_;
    
    public abstract class Template {
        public static void main(String[] args) {
            AA aa = new AA();
            BB bb = new BB();
            aa.getTime();
            bb.getTime();
        }
    
        public void getTime() {
            long startTime = System.currentTimeMillis();
            job();
            long endTime = System.currentTimeMillis();
            System.out.println("运行时间:" + (endTime - startTime));
        }
    
        public abstract void job();
    }
    
    class AA extends Template {
        @Override
        public void job() {
            long sum = 0;
            for (long i = 0; i < 100000; i++) {
                sum += i;
            }
        }
    }
    
    class BB extends Template {
        @Override
        public void job() {
            long sum = 0;
            for (long i = 0; i < 1000000; i++) {
                sum += i;
            }
        }
    }
    
    • 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

    二、接口

    基本介绍

    在这里插入图片描述
    注意:

    1. 在接口中抽象方法可以不加abstract
    2. jdk8及以后可以有默认方法但是要加default关键字,如果是静态方法不用加default

    接口使用的注意事项和使用细节(注意:4,6,8)

    在这里插入图片描述
    在这里插入图片描述

    实现接口VS继承类

    实现接口时对java单继承的补充

    • 当子类继承了父类就自动拥有了父类的功能
    • 如果子类需要拓展功能就需要通过实现接口的方式来拓展

    在这里插入图片描述

    接口的多态特性

    有点类似向上转型和向下转型

    在这里插入图片描述

    多态传递

    //I3实现了I1,I1继承了I2,所以接口I1和I2都可以使用I3的实例
    //或者说I3==>I1->I2,I1和I2都可以使用I3的实例
    interface I1 extends I2 {
    }
    
    interface I2 {
    }
    
    class I3 implements I1 {
    }
    
    
    public class Test {
        public static void main(String[] args) {
            I1 i1 = new I3();
            I2 i2 = new I3();
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    接口和抽象类的区别

    • 接口是对动作的抽象,抽象类是对本质的抽象
    • 接口中所有成员变量都是用public static final修饰的
    • 接口中没有构造器,没有main方法,因为它不是一个类
    • 抽象类是用来继承的(extends),接口是用来实现的(implements)
    • 接口是多继承的,抽象类是单继承的
    • 接口中声明默认方法要加default,静态方法可以不加
    • 接口中可以有静态方法不能有静态代码块,抽象类中可以有静态方法和静态代码块

    三、内部类(重点、难点)

    基本介绍

    在这里插入图片描述

    类的五大成员:属性,方法,构造器,代码块,内部类

    内部类的分类

    在这里插入图片描述

    局部内部类

    在这里插入图片描述
    在这里插入图片描述

    tips:因为在方法中,所以当成方法的一个局部变量,不过是以类的形式而存在的,所以可以访问外部类的成员但是不能添加访问修饰符,作用域也仅仅在定义它的方法或代码中,要使用也只能在方法中实例化对象

    案例:
    在这里插入图片描述

    
    interface Plants {
        void say();
    }
    
    class Animal {
        private String name;
    
        public Animal(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        void say() {
            System.out.println("我是动物" + getName());
        }
    }
    
    public class LocalInnerClass {
    
        public static void main(String[] args) {
    
            LocalInnerClass localInnerClass = new LocalInnerClass();
            localInnerClass.getAnimal();
            localInnerClass.getPlants();
    
        }
    
        //局部内部类--继承外部的一般类
        void getAnimal() {
    
            class Pig extends Animal {
                public Pig(String name) {
                    super(name);
                }
            }
            Animal animal = new Pig("猪");
            animal.say();
        }
    
        //局部内部类--实现外部的接口
        void getPlants() {
            class Tree implements Plants {
                String name;
    
                public Tree(String name) {
                    this.name = name;
                }
    
                @Override
                public void say() {
                    System.out.println("我是植物" + this.name);
                }
            }
            Plants plants = new Tree("树");
            plants.say();
        
    
    }
    
    
    • 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
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    匿名内部类(重要!!!)

    匿名内部类的使用

    在这里插入图片描述

    所谓的匿名实则是系统给的我们不知道而已,系统分配为***$1
    在这里插入图片描述
    在这里插入图片描述

    //前提:必须继承一个父类或实现一个接口
    interface Plants02 {
        String name = "apple tree";
    
        void say();
    }
    
    public class AnonymousInnerClass {
        int a = 1;
        String name = "pear tree";
    
        public static void main(String[] args) {
            AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass();
            anonymousInnerClass.getAnimal02();
            anonymousInnerClass.getPlant02();
        }
    
        //匿名内部类
        void getAnimal02() {
            //继承类式的
            Animal02 dog = new Animal02("二狗") {
                public void say() {
                    int a = 10;
                    System.out.println("我是" + getName());
                    System.out.println(a);//10
                    System.out.println(AnonymousInnerClass.this.a);//1
                }
    
                public void sayName() {
                }
            };
            dog.say();
    //        dog.sayName(),报错是因为dog的编译类型是Animal02,它没有sayName()方法
        }
    
        void getPlant02() {
            //实现接口式的
            Plants02 tree = new Plants02() {
                @Override
                public void say() {
                    System.out.println("我是树");
                    System.out.println(name);//apple tree
                    System.out.println(AnonymousInnerClass.this.name);//pear tree
                }
            };
            tree.say();
    
            //lambda表达式
            Plants02 trees = () -> System.out.println("我是树");
        }
    
    }
    
    class Animal02 {
        private String name;
    
        public Animal02(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        void say() {
            System.out.println("我是动物" + getName());
        }
    }
    
    • 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
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    注意和匿名对象的区别

            //下面的运行类型是Tiger
            Animal animal2 = new Tiger();
            //下面的运行类型是Outer$2
            Animal animal3 = new Tiger() {
            };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    匿名内部类使用的注意事项和细节

    tips:匿名内部类一般都是new 接口名/父类名 (){},创建出来的匿名内部类是“儿子”
    在这里插入图片描述

     public void f1() {
     		//这边是类 
            Person p = new Person() {
                @Override
                public void hi() {
                    System.out.println("内部hi() ");
                }
            };
            p.hi();
            //匿名内部类本身也是对象
            new Person() {
                @Override
                public void hi() {
                    System.out.println("新的内部hi() ");
                }
            }.hi();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    在这里插入图片描述

    匿名内部类的实践

    在这里插入图片描述
    和传统方法对比:

    interface Plant { 
        void show();
    }
    
    public class Use_ {
        public static void main(String[] args) {
            //使用匿名内部类
            f1(new Plant() {
                @Override
                public void show() {
                    System.out.println("wo shi plant");
                }
            });
            //传统方法
            f1(new Tree());
        }
    
        public static void f1(Plant plant) {
            plant.show();
        }
    }
    
    //传统方法
    class Tree implements Plant {
        @Override
        public void show() {
            System.out.println("wo shi tree");
        }
    }
    
    • 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

    成员内部类

    在这里插入图片描述

    public class OuterClass {
        int a = 1;
    
        public static void main(String[] args) {
            //调用成员内部类方法
            OuterClass outerClass = new OuterClass();
            outerClass.useInnerClass();
            //创建成员内部类对象,使用成员内部类属性,方法
            OuterClass.InnerClass innerClass = outerClass.new InnerClass();
            System.out.println(innerClass.name);
            innerClass.say();
        }
    
        public void useInnerClass() {
            InnerClass innerClass = new InnerClass();
            innerClass.say();
        }
    
        class InnerClass {
            String name = "内部类";
            int a = 10;
    
            void say() {
                System.out.println("我是内部类");
                System.out.println(a);//10
                System.out.println(OuterClass.this.a);//1
            }
        }
    }
    
    class OtherOuterClass {
        public static void main(String[] args) {
            // 外部其他类中使用
            OuterClass outerClass = new OuterClass();
            outerClass.useInnerClass();
            //创建成员内部类对象,使用成员内部类属性,方法
            OuterClass.InnerClass innerClass = outerClass.new InnerClass();
            System.out.println(innerClass.name);
            innerClass.say();
        }
    }
    
    
    • 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

    在这里插入图片描述
    第五点:
    在这里插入图片描述

    第六点:

    class OuterClass {
        public InnerClass02 getInnerClass() {
            return new InnerClass02();
        }
    
        class InnerClass {
        }
    
        class InnerClass02 {
        }
    }
    
    class Visit {
        public static void main(String[] args) {
            OuterClass outerClass = new OuterClass();
            //方式一
            OuterClass.InnerClass innerClass = outerClass.new InnerClass();
            //方式二
            OuterClass.InnerClass02 innerClass02 = outerClass.getInnerClass();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    静态内部类

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    public class StaticInnerClass {
        static int a = 1;
    
        public static void main(String[] args) {
            //静态内部类对象创建及使用
            InnerClass innerClass = new InnerClass();
            innerClass.say();
            StaticInnerClass.InnerClass innerClass1 = new InnerClass();
            innerClass1.say();
        }
    
        static class InnerClass {
            int a = 10;
    
            void say() {
                System.out.println("我是静态内部类");
                System.out.println(a);//10
                System.out.println(StaticInnerClass.a);//1
            }
        }
    }
    
    //在其他外部内中使用静态内部类
    class OtherOuterClass_ {
        public static void main(String[] args) {
            StaticInnerClass.InnerClass innerClass = new StaticInnerClass.InnerClass();
            innerClass.say();
        }
    }
    
    
    
    • 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

    在这里插入图片描述

  • 相关阅读:
    编译buildroot出错,这个怎么解决呢,感谢
    【随想】每日两题Day.5 (实则一题)
    记录--Three.js的简单使用,Three.js在vue3.x中导入.pcd三维模型文件
    Vue3学习(十五)之 级联选择组件Cascader的使用
    buildadmin+tp8表格操作(6)表格行中添加详情按钮并弹出对话框
    在 4GB 物理内存的机器上,申请 8G 内存会怎么样?
    怎么设计一个高质量的API接口
    2M误码仪 TFN T1000M E1/数据传输分析仪
    C语言——深入理解指针——函数指针
    SFI立昌在Mobile移动通话通讯设备的方案与应用
  • 原文地址:https://blog.csdn.net/weixin_43903745/article/details/126215919