锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

包 权限修饰符 final 常量 枚举 抽象类 接口 多态 内部类 常用API 正则表达式 Lambda

时间:2023-06-17 23:07:00 19sb1j电连接器

什么是包?

  1. 包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护。

  2. 包装语法格式:package 公司域名倒写.技术名称。注册建议所有英文小写,具有意义。

    package com.itheima.javabean; public class Student {    } 

  3. 建包语句必须在第一行,一般IDEA有助于创建工具

导包

  1. 可直接访问相同包下的类,不同包下的类必须导包才能使用!导包格式:import 包名.类名;

  2. 如果一个类别需要不同的类别,而这两个类别的名称是相同的,那么默认情况下只能导入一个类别,另一个类别需要带包名访问。

权限修饰符

权限修饰符是什么?

  • 权限修饰符:用于控制成员可访问的范围。

  • 可以修饰成员变量、方法、结构、内部类别,修访问不同权限修饰符的成员的范围将受到限制。

权限修饰符的分类及具体作用范围:

  • 权限修饰符:由小到大有四种作用(private -> 缺省 -> protected - > public )

    正在上传…重新上传取消

完成权限修饰符需要具备以下能力

  • 能够识别人定义的成员的访问权限。

  • 自定义成员(方法、成员变量、构造器等)一般满足以下要求:

    1. 成员变量一般是私有的。

    b. 该方法通常是公开的。

    c. 如果成员只想使用这种访问,private修饰。

    d. 如果该成员只想访问同一包下的其他类别和子类,则使用该类别protected修饰。

final

final的作用

final 关键词是最终的意思,可修饰(方法、变量、类)

修饰方法:表明该方法是最终方法,不能重写。

修改变量:表示变量第一次赋值后,不能再次赋值(而且只能赋值一次)。

修饰:说明这类是最终类,不能继承。

final注意修改变量

  • final修饰的变量是基本类型:然后存储变量**数据值**不能发生改变。

  • final修饰的变量是引用类型:变量存储的地址值不能改变,但地址指向的对象内容可以改变。

常量

常量概述和基本功能

常量

  1. 使用常量public static final修改后的成员变量必须具有初始值,其值在执行过程中不能改变。

  2. 常量的功能和好处:可用于制作系统配置信息,方便程序维护,提高可读性。

    常量命名规范:英文单词全部大写,多个单词下划线连接。

public class Constant {     public static final String SCHOOL_NAME  = “传智教育";     public static final String LOGIN_NAME  = “admin";     public static final String PASS_WORD  = “123456"; }  

常量执行原理

  1. 在编译阶段会进行“宏替换”,把使用常量的地方全部替换成真实的字面量。

  2. 这样做的好处是使用常量程序的执行性能与直接使用字面量相同。

常量信息标志和分类

为了控制玛丽移动的方向,现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号。

信息标志和分类选择常量: 实现软编码形式的代码可读性好。

枚举

枚举的概述

枚举的概述

  • 枚举是Java特殊类型之一

  • 枚举的作用:"做信息标志和信息分类"。

    定义枚举类格式:

    修饰符 enum 枚举名称{             第一行是列举枚举实例的名称。 } 
    enum Season{        SPRING , SUMMER , AUTUMN , WINTER; } 

    枚举的特征

    • 枚举类都继承了枚举类型:java.lang.Enum

    • 枚举是最后一类,不能继承。

    • 构造器是私有的,枚举不能创建对象。

    • 默认情况下,枚举类的第一行列出了枚举对象的名称。

    • 枚举类相当于多种模式。

使用场景演示枚举

案例说明: 为了控制玛丽移动的方向,现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号。

信息标志和分类选择常量: 虽然可以实现可读性,但参数不受限制,代码相对不够严格。

枚举作为信息标志和分类: 最好的信息分类技术是代码可读性好,入参约束严谨,代码优雅!推荐使用!

抽象类

抽象类概述

-在Java中abstract这意味着抽象。如果一个类别中某种方法的具体实现不能确定,则可以声明为abstract修饰抽象方法(不能写方法体),这一类必须使用abstract修饰,叫抽象类。

修饰符 abstract 返回值类型 方法名称(形参列表);

修饰符 abstract class 类名{ }

public abstract class Animal{     public abstract void run(); } 

抽象使用总结和注意事项

  • 抽象类可以理解为被子类继承的不完整设计图。

  • 如果一个类继承了抽象类,那么这个类必须重写抽象类的所有抽象方法,否则,这一类也必须定义为抽象类。

    总结

    1.抽象的作用是什么? 它可以被子类继承,作为模板,也可以改进代码重用。 2.抽象方法是什么? 只有方法签名,没有方法体,使用abstract修饰。 3.继承抽象有哪些注意事项? 如果一个类继承了抽象类,那么这个类必须重写抽象类的所有抽象方法。 否则,这一类也必须定义为抽象类。

抽象案例

系统需求 某加油站推出了两种支付卡,一种是预存1万张金卡,后续加油享受80%的折扣,另一种是预存5万张银卡 ,后续加油享受8.5折优惠。 进入出纳系统后,请分别实现两张卡的逻辑,卡需要包含主人的名称、余额、支付功能。

分析实现 创建卡片父类:定义属性包括主人名称、余额、支付功能(具体实现子类) 创建一张白金卡类:重写支付功能,按照原价的8折计算输出。 创建银卡类:重写支付功能,按原价8.五折计算输出。

package com.itheima.d7_abstract_test;  public abstract class Card {     private String userName;     private double money; //定义支付方式,表示卡可以支付。     ///抽象方法     public abstract void pay(double money);     public String getUserName() {         return userName;     }      public void setUserName(String userName) {         this.userName = userName;     }      public double getMoney() {         return money;     }      public void setMoney(double money) {         this.money = money;     } }
package com.itheima.d7_abstract_test;  public class GoldCard extends Card {     @Override     public void pay(double money2) {         System.out.println("您目前的消费:" money2);         System.out.println("您目前的余额:" getMoney());         //优惠价        double rs=money2*0.8;
        System.out.println("您实际支付:"+rs);
        //更新账户余额
        setMoney(getMoney()-rs);
    }
}

package com.itheima.d7_abstract_test;

public class Test {
    public static void main(String[] args) {
        //学习抽象类的基本使用,做父类,被继承,重写抽象方法
        GoldCard c=new GoldCard();
        c.setMoney(10000);
        c.setUserName("贾明超");
        c.pay(300);
        System.out.println("剩余:"+c.getMoney());

    }
}

抽象类的特征、注意事项

特征和注意事项

  • 有得有失: 得到了抽象方法,失去了创建对象的能力。

  • 抽象类为什么不能创建对象?

  • 类有的成员(成员变量、方法、构造器)抽象类都具备

  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

  • 一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必

    须定义成抽象类。

  • 不能用abstract修饰变量、代码块、构造器。

    final和abstract是什么关系?

    • 互斥关系

    • abstract定义的抽象类作为模板让子类继承,final定义的类不能被继承。

    • 抽象方法定义通用功能让子类重写,final定义的方法子类不能重写。

抽象类的应用知识:模板方法模式

  • 使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候。

    使用步骤

    1. 把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。

    2. 模板方法中不能决定的功能定义成抽象方法让具体子类去实现。

      package com.itheima.d9_abstract_template;
      
      public abstract class Student {
          //正式声明了模板方法模式
          public final void write(){//防止子类重写以防改模板
              System.out.println("\t\t\t\t我的爸爸");
              System.out.println("你的爸爸是啥样");
              //正文(每个子类都要写的,每个子类写的情况不一样)
              //因此,模板方法把正文部分定义成抽象方法,交给具体的子类来完成
              System.out.println(writeMain());//就近选择子类重写的方法
              System.out.println("我的爸爸简直太好了");
          }
          public abstract String writeMain();
      }
      
      package com.itheima.d9_abstract_template;
      
      public class StudentChild extends Student {
      
          @Override
          public String writeMain() {
      
              return"我的爸爸太牛了";
          }
      }
      
      
      package com.itheima.d9_abstract_template;
      
      public class StudentMiddle extends Student{
      
          @Override
          public String writeMain() {
              return "我的爸爸也很牛";
          }
      }
      
      package com.itheima.d9_abstract_template;
      
      public class Test {
          public static void main(String[] args) {
              //模板方法模式思想和使用步骤。
              //写作文,中学生和小学生都写《我的爸爸》,开头结尾固定,正文自由发挥。
             StudentMiddle s=new StudentMiddle();
             s.write();
             StudentChild s2=new StudentChild();
             s2.write();
          }
      }
      

      模板方法我们是建议使用final修饰的,这样会更专业**

      总结

      • 模板方法模式解决了什么问题?

        1. 极大的提高了代码的复用性

        2. 模板方法已经定义了通用结构,模板不能确定的定义成抽象方法。

        3. 使用者只需要关心自己需要实现的功能即可。

接口

接口概述、特点

接口的定义与特点

  • 接口的格式如下:

接口用关键字interface来定义
public interface 接口名 {
       // 常量
       // 抽象方法
}
  • JDK8之前接口中只能是抽象方法和常量,没有其他成分了。

  • 接口不能实例化。

  • 接口中的成员都是public修饰的,写不写都是,因为规范的目的是为了公开化。

    package com.itheima.d10_interface;
    //声明的接口:体现了一种规范,规范一定是公开的。
    public interface InterfaceDome {
        //接口中的成分特点:JDK8之前接口中只有抽象方法和常量
        //1.常量
    //    public static final String SCHOOL_NAME="黑马程序员";
    
        String SCHOOL_NAME="黑马程序员";
        //2.抽象方法
        //注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract可以省略不写。
    //  public abstract void run();
    
        void run();
    }

接口的基本使用:被实现

接口的用法:

  • 接口是用来被类实现(implements)的,实现接口的类称为实现类。实现类可以理解成所谓的子类。

    修饰符 class 实现类 implements 接口1, 接口2, 接口3 , ... {
    }
    实现的关键字:implements
    

    从上面可以看出,接口可以被类单实现,也可以被类多实现。

接口实现的注意事项:

  • 一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类。

    package com.itheima.d11_implements;
    
    public interface Law {
        void rule();
    }
    
    package com.itheima.d11_implements;
    
    public interface SportMan {
        void run();
        void competition();
    }
    
    package com.itheima.d11_implements;
    
    public class PingpongMan implements SportMan,Law{
        private String name;
    
        public PingpongMan(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            System.out.println(name+"必须训练");
        }
    
        @Override
        public void competition() {
            System.out.println(name+"必须参加比赛");
    
        }
    
        @Override
        public void rule() {
    
        }
    }
    
    package com.itheima.d11_implements;
    
    public class Test {
        public static void main(String[] args) {
            //理解接口的基本使用,被类实现。
            PingpongMan p=new PingpongMan("张继科");
            p.run();
            p.competition();
            p.rule();
        }
    }
    

接口与接口的关系:多继承

基本小结

  • 类和类的关系:单继承。

  • 类和接口的关系:多实现。

  • 接口和接口的关系:多继承,一个接口可以同时继承多个接口。

接口多继承的作用

规范合并,整合多个接口为同一个接口,便于子类实现。

JDK8开始接口新增方法

允许接口中直接定义带有方法体的方法

正在上传…重新上传取消

正在上传…重新上传取消

正在上传…重新上传取消

总结

  • JDK8开始后新增了那些方法?

  • 默认方法:default修饰,实现类对象调用。

  • 静态方法:static修饰,必须用当前接口名调用

  • 私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。 他们都会默认被public修饰。

使用接口的注意事项

1、接口不能创建对象 2、一个类实现多个接口,多个接口中有同样的静态方法不冲突。 3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。 4、一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可。 5、一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。

面向对象三大特征之三:多态

多态的概述,多态的形式

什么是多态?

  • 同类型的对象,执行同一个行为,会表现出不同的行为特征。

多态的常见形式

父类类型 对象名称 = new 子类构造器;
接口     对象名称 = new 实现类构造器;	

多态中成员访问特点

  • 方法调用:编译看左边,运行看右边。

  • 变量调用:编译看左边,运行也看左边。(多态侧重行为多态)

多态的前提

有继承/实现关系;有父类引用指向子类对象;有方法重写。

package com.itheima.d1_polymorphic;

public abstract class Animal {
    public String name="父类动物";
    public abstract void run();
}
package com.itheima.d1_polymorphic;

public class Dog extends Animal{
    public String name="子类狗";
    @Override
    public void run() {
        System.out.println("狗跑的贼快");
    }
}
package com.itheima.d1_polymorphic;

public class Tortoise extends Animal{
    public String name="子类乌龟";
    @Override
    public void run() {
        System.out.println("乌龟根本不会跑");
    }
}
package com.itheima.d1_polymorphic;

public class Test {
    public static void main(String[] args) {
//1.多态的形式:
        Animal a=new Dog();
        a.run();//方法调用:编译看左边,运行看右边
        System.out.println(a.name);//变量调用:编译运行都看左

        Animal a2=new Tortoise();
        a2.run();
        System.out.println(a2.name);//父类动物
    }
}

多态的好处

优势

在多态形式下,右边对象可以实现解耦合,便于扩展和维护。 定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利。

Animal a = new Dog();
a.run(); // 后续业务行为随对象而变,后续代码无需修改

多态下会产生的一个问题:

多态下不能使用子类的独有功能

多态下引用数据类型的类型转换

自动类型转换(从子到父):

  • 子类对象赋值给父类类型的变量指向。

强制类型转换吗(从父到子)

  • 此时必须进行强制类型转换:子类 对象变量 = (子类)父类类型的变量 作用:可以解决多态下的劣势,可以实现调用子类独有的功能。

  • 注意: 如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException

  • Java建议强转转换前使用instanceof判断当前对象的真实类型,再进行强制转换

    变量名 instanceof 真实类型
    判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true,反之。
package com.itheima.d3_polymorphic_convert.d1_polymorphic;

public abstract class Animal {
    public String name="父类动物";
    public abstract void run();
}
package com.itheima.d3_polymorphic_convert.d1_polymorphic;

public class Dog extends Animal {
    public String name="子类狗";
    @Override
    public void run() {System.out.println("狗跑的贼快");}
    //独有功能
    public void lookDoor(){
        System.out.println("狗在看门");
    }
}
package com.itheima.d3_polymorphic_convert.d1_polymorphic;

public class Tortoise extends Animal {
    public String name="子类乌龟";
    @Override
    public void run() {
        System.out.println("乌龟根本不会跑");
    }
    public void leyEggs(){
        System.out.println("乌龟会下蛋");
    }
}
package com.itheima.d3_polymorphic_convert.d1_polymorphic;

public class Test {
    public static void main(String[] args) {
      //自动类型转换
        Animal a=new Dog();
        a.run();
        //强制类型转换
        Animal a2=new Tortoise();
        a2.run();

       // Dog d= (Dog) a2;//强制类型转换,编译阶段不报错。(注意:有继承或者实现关系编译阶段可以强转。运行时可能出错)
        if(a2 instanceof Tortoise){
            Tortoise t= (Tortoise) a2;
            t.leyEggs();
        }else if(a2 instanceof Dog){
            Dog d=new Dog();
            d.lookDoor();
        }
        System.out.println("............................");
        go(new Dog());
        go(new Tortoise());
    }
    public static void go(Animal a){
        a.run();
        //不知道a是狗还是乌龟
        if(a instanceof Tortoise){
            Tortoise t= (Tortoise) a;
            t.leyEggs();
        }else if(a instanceof Dog){
            Dog d= (Dog) a;
            d.lookDoor();
        }
    }
}

总结

  1. 引用数据类型的类型转换,有几种方式? 自动类型转换、强制类型转换。

  2. 强制类型转换能解决什么问题?强制类型转换需要注意什么。

    a. 可以转换成真正的子类类型,从而调用子类独有功能。

    b.有继承关系/实现的2个类型就可以进行强制转换,编译无问题。 c.运行时,如果发现强制转换后的类型不是对象真实类型则报错。 类型转换异常:ClassCastException

多态的综合案例

需求: 使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备 鼠标:被安装时可以完成接入、调用点击功能、拔出功能。 键盘:被安装时可以完成接入、调用打字功能、拔出功能。 分析 定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。 提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。 创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。

package com.itheima.d4_polymorphic_test;

public class Computer {

    private String name;

    public Computer(String name) {
        this.name = name;
    }
    public void start(){
        System.out.println(name+"开机了");
    }
    //   提供安装USB设备的入口
    public void installUSB(USB usb){
        //多态。父类接口作为入参。usb可能是鼠标还可能是键盘
        usb.connect();
        //独有功能:判断 强转
        if (usb instanceof KeyBoard){
            KeyBoard k= (KeyBoard) usb;
            k.keyDown();
        }else if(usb instanceof Mouse){
            Mouse m= (Mouse) usb;
            m.dbClick();
        }

        usb.unconnect();
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package com.itheima.d4_polymorphic_test;
//USB接口==规范
public interface USB {
//接入 拔出
    void connect();
    void unconnect();
}
package com.itheima.d4_polymorphic_test;

public class KeyBoard implements USB{
    private String name;
//独有功能
    public void keyDown(){
        System.out.println(name+"敲击了");
    }

    public KeyBoard(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void connect() {
        System.out.println("成功连接了电脑");
    }
    @Override
    public void unconnect() {
        System.out.println("成功断开了电脑");
    }
}
package com.itheima.d4_polymorphic_test;

public class Mouse implements USB{
    private String name;
    //独有功能
    public void dbClick(){
        System.out.println(name+"双击点亮小红心");
    }

    public Mouse(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void connect() {
        System.out.println("成功连接了电脑");
    }
    @Override
    public void unconnect() {
        System.out.println("成功断开了电脑");
    }
}
package com.itheima.d4_polymorphic_test;
//定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。
//        提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。
//        创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。
public class Test {
    public static void main(String[] args) {
        //1.创建电脑对象
        Computer c=new Computer("外星人");
        c.start();
        //2.创建鼠标对象,键盘对象
        USB u=new KeyBoard("双飞燕");
        c.installUSB(u);
        USB u1=new Mouse("罗技鼠标");
        c.installUSB(u1);

    }
}

内部类

内部类概述

内部类

  • 内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)。

  • public class People{
        // 内部类
        public class Heart{
        }
    }

内部类的使用场景、作用

  • 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计。

  • 内部类通常可以方便访问外部类的成员,包括私有的成员。

  • 内部类提供了更好的封装性,内部类本身就可以用private protectecd等修饰,封装性可以做更多控制。

内部类的分类

  1. 静态内部类[了解]

  2. 成员内部类(非静态内部类) [了解]

  3. 局部内部类[了解]

  4. 匿名内部类(重点)

内部类之一:静态内部类[了解]

什么是静态内部类?

  • 有static修饰,属于外部类本身。

  • 它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已。

    public class Outer{
            // 静态成员内部类
        public static class Inner{
        }
    }
    
  • 静态内部类创建对象的格式:

    外部类名.内部类名 对象名 = new 外部类名.内部类构造器;
    范例:Outer.Inner in =  new Outer.Inner();
    
    package com.itheima.d5_innerclass_static;
    //外部类
    public class Outer {
        public static int a=100;
        private String hobby;
        public static class Inner{
            private String name;
            private int age;
            public static String schoolName;
    
            public Inner() {
            }
    
            public Inner(String name, int age) {
                this.name = name;
                this.age = age;
            }
            public void show(){
                System.out.println("名称:"+name);
                System.out.println(a);
    //            System.out.println(hobby);
    //            Outer o=new Outer();
    //            System.out.println(o.hobby);可以直接访问外部类的静态成员,不能直接访问外部类的实例成员。
            }
            public String getName() {
                return name;
    
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public int getAge() {
                return age;
            }
    
            public void setAge(int age) {
                this.age = age;
            }
    
            public static String getSchoolName() {
                return schoolName;
            }
    
            public static void setSchoolName(String schoolName) {
                Inner.schoolName = schoolName;
            }
        }
    }
    
    package com.itheima.d5_innerclass_static;
    
    public class Test {
        public static void main(String[] args) {
            Outer.Inner in=new Outer.Inner();
            in.setName("张三");//张三
            in.show();//100
        }
    }
    

静态内部类的访问拓展:

1、静态内部类中是否可以直接访问外部类的静态成员? 可以,外部类的静态成员只有一份可以被共享访问。 2、静态内部类中是否可以直接访问外部类的实例成员? 不可以的,外部类的实例成员必须用外部类对象访问。

内部类之二:成员内部类[了解]

什么是成员内部类?

  • 无static修饰,属于外部类的对象。

    public class Outer {
        // 成员内部类 
        public class Inner {    
        }
    }
    

  • JDK16之前,成员内部类中不能定义静态成员,JDK 16开始也可以定义静态成员了。

  • 成员内部类创建对象的格式:

格式:
    外部类名.内部类名 对象名 = new  外部类构造器.new 内部类构造器();
范例:
    Outer.Inner in =  new Outer().new  Inner();

成员内部类的访问扩展

1、成员内部类中是否可以直接访问外部类的静态成员? 可以,外部类的静态成员只有一份可以被共享访问。 2、成员内部类的实例方法中是否可以直接访问外部类的实例成员? 可以的,因为必须先有外部类对象,才能有成员内部类对象,所以可以直接访问外部类对象的实例成员

package com.itheima.d6_innerclass;

//外部类
public class Outer {
    //成员内部类:不能加static修饰
    public static int num=11;
    private String hobby;

    public Outer() {
    }

    public Outer(String hobby) {
        this.hobby = hobby;
    }

    public class Inner {
        private String name;
        private int age;
        public static int a=100;//JDK 16开始也可以定义静态成员了

        public static void test(){
            System.out.println(a);
        }
        public void show() {
            System.out.println("名称:"+name);
            System.out.println("数量:"+num);
            System.out.println("爱好:"+hobby);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public static int getA() {
            return a;
        }

        public static void setA(int a) {
            Inner.a = a;
        }
    }
}
package com.itheima.d6_innerclass;

public class Test {
    public static void main(String[] args) {
        Outer.Inner in=new Outer().new Inner();
        in.setName("内部");
        in.show();
        Outer.Inner.test();

        System.out.println("......................");
        Outer.Inner in1=new Outer("爱学习").new Inner();
        in1.show();
    }
}
//名称:内部
数量:11
爱好:null
100
......................
名称:null
数量:11
爱好:爱学习

内部类之三:局部内部类[了解]

局部内部类 (鸡肋语法,了解即可) 局部内部类放在方法、代码块、构造器等执行体中。 局部内部类的类文件名为: 外部类$N内部类.class。

内部类之四:匿名内部类概述[重点]

匿名内部类:

本质上是一个没有名字的局部内部类,定义在方法中、代码块中、等。 作用:方便创建子类对象,最终目的为了简化代码编写。

格式:

new 类|抽象类名|或者接口名() {
    重写方法;
};
Animal a = new Animal() {
    public void run() {
    }
};
a. run();

(可以理解为既是一个类也是一个对象)

特点总结:

  • 匿名内部类是一个没有名字的内部类。

  • 匿名内部类写出来就会产生一个匿名内部类的对象。

  • 匿名内部类的对象类型相当于是当前new的那个的类型的子类类型

匿名内部类常见使用形式

Test1

package com.itheima.d8_innerclass_anoymous;

public class Test {
    public static void main(String[] args) {
        Animal a=new Animal() {
            @Override
            public void run() {
                System.out.println("老虎跑得快");
            }
        };
        a.run();
    }
}

//class Tiger extends Animal{
//    @Override
//    public void run() {
//        System.out.println("老虎跑得快");
//    }
//}

abstract class Animal{
    public abstract void run();
}
老虎跑得快

Test2

package com.itheima.d8_innerclass_anoymous;
//掌握匿名内部类的使用形式(语法)
public class Test2{
    public static void main(String[] args) {
 //     Swimming s=new Student();
        Swimming s=new Swimming() {
            @Override
            public void swim() {
                System.out.println("学生自由泳");
            }
        };
        go(s);
        System.out.println("..................");
        Swimming s1=new Swimming() {
            @Override
            public void swim() {
                System.out.println("老师游得贼快");
            }
        };
        go(s1);
        System.out.println(".................");

        go(new Swimming() {
            @Override
            public void swim() {
                System.out.println("运动员游得贼快");
            }
        });
    }
    //学生老师运动员可以一起参加比赛
    //接口充当一种父类,所有子类都可以送进来
   public static void go(Swimming s){
       System.out.println("开始");
       s.swim();
       System.out.println("结束");
   }
}
//class Student implements Swimming{
//    @Override
//    public void swim() {
//        System.out.println("学生快乐的游泳");
//    }
//}

//会游泳
 interface Swimming{
    void swim();
}
开始
学生自由泳
结束
..................
开始
老师游得贼快
结束
.................
开始
运动员游得贼快
结束

匿名内部类真实使用场景演示

正在上传…重新上传取消

常用API

Object

Object类的方法

  • Object类的方法是一切子类对象都可以直接使用的,所以我们要学习Object类的方法。

  • 一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类。

    PUBLIC STRING TOSTRING() 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址
    public boolean equals(Object o) 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false

toString方法

问题引出

开发中直接输出对象,默认输出对象的地址其实是毫无意义的。 开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息。

toString存在的意义

父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息!!

equals方法

问题提出

直接比较两个对象的地址是否相同完全可以用“==”替代equals。

equals存在的意义

父类equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则。

总结

Object的equals方法的作用是什么?

  • 默认是与另一个对象比较地址是否一样

  • 让子类重写,以便比较2个子类对象的内容是否相同。

    package com.itheima.d9_api_object;
    
    import java.util.Objects;
    
    public class Student {//extends Object
        private String name;
        private char sex;
        private int age;
    
        public Student() {
        }
    
        public Student(String name, char sex, int age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public char getSex() {
            return sex;
        }
    
        public void setSex(char sex) {
            this.sex = sex;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        //重写equals,自己定制相等规则。两个对象内容一样就认为是相等的。比较者:s1==this(谁调这个方法,this就代表谁)
        // 被比较者:s2==>o
    
    //    @Override
    //    public boolean equals(Object o) {
    //        //1.判断o是不是学生类型
    //        if (o instanceof Student) {
    //            Student s2 = (Student) o;//强转成学生类型,才能调用学生类中的独有属性
    //            //2.判断两个对象内容是否一样
                if (this.name.equals(s2.name) && this.age == s2.age && this.sex == s2.sex) {
                    return true;
                }else{
                    return false;
                }
    //            return this.name.equals(s2.name) && this.age == s2.age && this.sex == s2.sex;
    //        } else {
    //            //学生只能和学生比,否则结果一定是false
    //            return false;
    //        }
    //    }
    
    
        @Override
        public boolean equals(Object o) {
            //1.判断是否为同一个对象比较,如果是返回true
            if (this == o) return true;
            //2.如果o==null 返回false,如果o不是学生类型返回false
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return sex == student.sex && age == student.age && Objects.equals(name, student.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, sex, age);
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", sex=" + sex +
                    ", age=" + age +
                    '}';
        }
    }
    
    package com.itheima.d9_api_object;
    
    public class Test1 {
        public static void main(String[] args) {
            //掌握object类中toString方法的使用
            Student s=new Student("贾明超",'男',19);
            String rs=s.toString();
            System.out.println(rs);
            //直接输出对象变量,默认可以省略toString调用不写的
            System.out.println(s);
        }
    }
    
    package com.itheima.d9_api_object;
    //掌握Object类中equals方法的使用
    public class Test2 {
        public static void main(String[] args) {
            Student s1=new Student("贾明超",'男',19);
            Student s2=new Student("贾明超",'男',19);
            //equals默认是比较两个不同的对象对象地址是否相同
            System.out.println(s1.equals(s2));//true 重写后
            System.out.println(s1 == s2);//false
        }
    }
    

Objects

Objects是一个工具类,提供了一些方法去完成一些功能。

官方在进行字符串比较时,没有用字符串对象的的equals方法,而是选择了Objects的equals方法来比较。

@Override
public boolean equals(Object o) {
    
    // 1、判断是否是同一个对象比较,如果是返回true。
    if (this == o) return true;
    // 2、如果o是null返回false  如果o不是学生类型返回false  ...Student !=  ..Pig
    if (o == null || this.getClass() != o.getClass()) 
        return false;
    // 3、说明o一定是学生类型而且不为null
    Student student = (Student) o;
    return sex == student.sex && age == student.age && Objects.equals(name, student.name);
}
方法名 说明
public static boolean equals(Object a, Object b) 比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常。再进行equals比较
public static boolean isNull(Object obj) 判断变量是否为null ,为null返回true ,反之

使用Objects的equals方法在进行对象的比较会更安全。

package com.itheima.d10_api_objects;

import java.util.Objects;

//掌握objects类的常用方法:equals
public class Test {
    public static void main(String[] args) {
        String s1=null;
        String s2=new String("itheima");
//        System.out.println(s1.equals(s2));//留下了隐患,可能出现了空指针异常。
        System.out.println(Objects.equals(s1,s2));//false 更安全,结果也是对的

        System.out.println(Objects.isNull(s1));//true
        System.out.println(s1==null);//true
        System.out.println(Objects.isNull(s2));//false
        System.out.println(s2==null);//false

    }
}

StringBuilder

方法名称 说明
public StringBuilder append(任意类型) 添加(连接)数据并返回StringBuilder对象本身
public StringBuilder reverse() 将对象的内容反转
public int length() 返回对象内容长度
public String toString() 通过toString()就可以实现把StringBuilder转换为String

为什么拼接、反转字符串建议使用StringBuilder?

  • String :内容是不可变的、拼接字符串性能差。

  • StringBuilder:内容是可变的、拼接字符串性能好、代码优雅。

  • 定义字符串使用String

  • 拼接、修改等操作字符串使用StringBuilder

    package com.itheima.d11_api_StringBuilder;
    
    public class StringBuilderDome1 {
        public static void main(String[] args) {
            StringBuilder sb=new StringBuilder();
            sb.append("a");
            sb.append("abc");
            sb.append(1);
            System.out.println(sb);
    
            StringBuilder sb1=new StringBuilder();
            //支持链式编程
            sb1.append("a").append("b").append("我爱你中国");
            System.out.println(sb1);//ab我爱你中国
    
            //反转
            sb1.reverse().append("110");
            System.out.println(sb1);//国中你爱我ba110
    
            //长度
            System.out.println(sb1.length());
    
            //注意:目的StringBuilder只是拼接字符串的手段,效率好。
            //最终的还是要恢复String类型。
            StringBuilder sb2=new StringBuilder();
            sb2.append("123").append("456");
            //恢复 String
            String rs=sb2.toString();
            check(rs);
        }
        public static void check (String data){
            System.out.println(data);
        }
    }
    
    
    package com.itheima.d11_api_StringBuilder;
    
    public class StringBuilderTest2 {
        public static void main(String[] args) {
            int []arr1=null;
            System.out.println(toString(arr1));
            int []arr2={10,20,30};
            System.out.println(toString(arr2));
        }
    
        //1.定义方法接受任意整型数组,返回数组内容格式
        public static String toString(int[] arr) {
            if (arr != null) {
                //2.开始拼接内容
                StringBuilder sb = new StringBuilder("[");//可以用有参构造器
                for (int i = 0; i < arr.length; i++) {
                    sb.append(arr[i]).append(i == arr.length - 1 ? "" : ", ");
                }
                sb.append("]");
                return sb.toString();
            } else {
                return null;
            }
    
        }
    }
    

Math

Math类

包含执行基本数字运算的方法,Math类没有提供公开的构造器,相当于一个工具类,不能创建对象。 如何使用类中的成员呢?看类的成员是否都是静态的,如果是,通过类名就可以直接调用.

Math类常用方法

方法名 说明
public static int abs(int a) 获取参数绝对值
public static double ceil(double a) 向上取整
public static double floor(double a) 向下取整
public static int round(float a) 四舍五入
public static int max(int a,int b) 获取两个int值中的较大值
public static double pow(double a,double b) 返回**a的b次幂的值 **
public static double random() 返回值为double的随机值,范围**[0.0,1.0)**
package com.itheima.d12_math;

/**
 目标:Math类的使用。
 Math用于做数学运算。
 Math类中的方法全部是静态方法,直接用类名调用即可。
 方法:
 方法名                                          说明
 public static int abs(int a)                   获取参数a的绝对值:
 public static double ceil(double a)            向上取整
 public static double floor(double a)           向下取整
 public static double pow(double a, double b)   获取a的b次幂
 public static long round(double a)             四舍五入取整
 小结:
 记住。
 */
public class MathDome {
    public static void main(String[] args) {
        // 1.取绝对值:返回正数
        System.out.println(Math.abs(10)); // 10
        System.out.println(Math.abs(-10.3)); // 10.3

        // 2.向上取整: 5
        System.out.println(Math.ceil(4.00000001)); // 5.0
        System.out.println(Math.ceil(4.0)); // 4.0
        // 3.向下取整:4
        System.out.println(Math.floor(4.99999999)); // 4.0
        System.out.println(Math.floor(4.0)); // 4.0

        // 4.求指数次方
        System.out.println(Math.pow(2 , 3)); // 2^3 = 8.0
        // 5.四舍五入 10
        System.out.println(Math.round(4.49999)); // 4
        System.out.println(Math.round(4.500001)); // 5

        System.out.println(Math.random());  // 0.0 - 1.0 (包前不包后)

        // 拓展: 3 - 9 之间的随机数  (0 - 6) + 3
        //  [0 - 6] + 3
        int data =  (int)(Math.random() * 7) + 3;
        System.out.println(data);


    }
}

System

System 类概述

System也是一个工具类,代表了当前系统,提供了一些与系统相关的方法。

System类常用方法

方法名 说明
public static void exit(int status) 终止当前运行的 Java 虚拟机,非零表示异常终止
public static long currentTimeMillis() 返回当前系统的时间毫秒值形式
public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数) 数组拷贝
package com.itheima.d13_system;

import java.lang.reflect.Array;
import java.util.Arrays;

public class SystemDemo {
    public static void main(String[] args) {
        System.out.println("程序开始");
//        System.exit(0);//JVM终止!静态方法属于类,用类调用。 0表示正常终止。
        System.out.println("程序结束");

//        2.计算机认为时间是有起点的,起始时间: 1970年1月1日  00:00:00
//        时间毫秒值:指的是从1970年1月1日    00:00:00走到此刻的总的毫秒数,应该是很大的。 1s = 1000ms。
        long time=System.currentTimeMillis();
        System.out.println(time);
        long startTime=System.currentTimeMillis();
        //进行时间的计算:性能分析
        for (int i = 0; i < 100000; i++) {
            System.out.println("输出:"+i);
        }
        long endTime=System.currentTimeMillis();
        System.out.println((endTime-startTime)/1000.0+"s");

        //3.数组拷贝
//        参数一:被拷贝的数组
//        参数二:从那个索引位置开始拷贝
//        参数三:复制的目标数组
//        参数四:粘贴位置
//        参数五:拷贝元素的个数

        int[] arr1={10,20,30,40};
        int[] arr2=new int[4];//[0,0,0,0]==>[0,0,30,40]
        System.arraycopy(arr1,2,arr2,2,2);
        System.out.println(Arrays.toString(arr2));
    }
}

BigDecimal

BigDecimal作用

用于解决浮点型运算精度失真的问题

使用步骤

创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)

public static BigDecimal valueOf(double val):包装浮点数成为BigDecimal对象。
package com.itheima.d14_bigdecimal;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;

/**
 目标:BigDecimal大数据类。

 引入:
 浮点型运算的时候直接+  * / 可能会出现数据失真(精度问题)。
 BigDecimal可以解决浮点型运算数据失真的问题。

 BigDicimal类:
 包:java.math.
 创建对象的方式(最好的方式:)
 public static BigDecimal valueOf(double val) :包装浮点数成为大数据对象。
 方法声明
 public BigDecimal add(BigDecimal value)       加法运算
 public BigDecimal subtract(BigDecimal value)  减法运算
 public BigDecimal multiply(BigDecimal value)  乘法运算
 public BigDecimal divide(BigDecimal value)    除法运算
 public double doubleValue(): 把BigDecimal转换成double类型。
 */
public class BigDecimalDemo {
    public static void main(String[] args) {
        // 浮点型运算的时候直接+  * / 可能会出现数据失真(精度问题)。
        System.out.println(0.09 + 0.01);
        System.out.println(1.0 - 0.32);
        System.out.println(1.015 * 100);
        System.out.println(1.301 / 100);

        System.out.println("-------------------------");
        double a = 0.1;
        double b = 0.2;
        double c = a + b;
        System.out.println(c);
        System.out.println("--------------------------");
        // 包装浮点型数据成为大数据对象 BigDeciaml
        BigDecimal a1 = BigDecimal.valueOf(a);
        BigDecimal b1 = BigDecimal.valueOf(b);
        BigDecimal c1 = a1.add(b1);
        // BigDecimal c1 = a1.subtract(b1);
        // BigDecimal c1 = a1.multiply(b1);
        // BigDecimal c1 = a1.divide(b1);
        System.out.println(c1);

        // 目的:double
        double rs = c1.doubleValue();
        System.out.println(rs);

        // 注意事项:BigDecimal是一定要精度运算的
        BigDecimal a11 = BigDecimal.valueOf(10.0);
        BigDecimal b11 = BigDecimal.valueOf(3.0);
        /**
         参数一:除数 参数二:保留小数位数  参数三:舍入模式
         */
        BigDecimal c11 = a11.divide(b11, 2, RoundingMode.HALF_UP); // 3.3333333333
        System.out.println(c11);


        System.out.println("-------------------");
    }
}

0.09999999999999999
0.6799999999999999
101.49999999999999
0.013009999999999999
-------------------------
0.30000000000000004
--------------------------
0.3
0.3
3.33
-------------------

BigDecima常用API

方法名 说明
public BigDecimal add(BigDecimal b) 加法
public BigDecimal subtract(BigDecimal b) 减法
public BigDecimal multiply(BigDecimal b) 乘法
public BigDecimal divide(BigDecimal b) 除法
public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式) 除法

日期与时间

Date 类

Date类概述

Date类代表当前所在系统的日期时间信息。

Date的构造器

名称 说明
public Date() 创建一个Date对象,代表的是系统当前此刻日期时间。

Date的方法

名称 说明
public long getTime() 返回从1970年1月1日 00:00:00走到此刻的总的毫秒数

案例

请计算出当前时间往后走1小时121秒之后的时间是多少。

时间毫秒值 -> 日期对象

构造器 说明
public Date(long time) 把时间毫秒值转换成Date日期对象。
DATE方法 说明
public void setTime(long time) 设置日期对象的时间为当前时间毫秒值对应的时间
package com.itheima.d1_date;

import java.util.Date;

//目标:学会使用 data类处理时间,获取时间信息。
public class DataDemo1 {
    public static void main(String[] args) {
        //1.创建一个Data类对象,代表系统此刻的日期时间对象
        Date d=new Date();
        System.out.println(d);
        //2.获取时间毫秒值
        long time=d.getTime();
        System.out.println(time);
        long time1=System.currentTimeMillis();
        System.out.println(time1);
        System.out.println("....................");
        //1.得到当前时间的毫秒值
        Date d1=new Date();
        System.out.println(d1);
        //2.当前时间往后走1小时121秒
        long time2=System.currentTimeMillis();
        time2+=(60*60+121)*1000;
        //3.把时间毫秒值转换成对应的日期对象
//        Date d2=new Date(time2);
//        System.out.println(d2);
        Date d3=new Date();
        d3.setTime(time2);
        System.out.println(d3);
    }
}
Mon Apr 11 14:25:23 CST 2022
1649658323951
1649658323981
....................
Mon Apr 11 14:25:23 CST 2022
Mon Apr 11 15:27:24 CST 2022

总结

  1. 日期对象如何创建,如何获取时间毫秒值?

    • public Date();

    • public long getTime();

  2. 时间毫秒值怎么恢复成日期对象

  • public Date(long time);

  • public void setTime(long time);

SimpleDateFormat

正在上传…重新上传取消

正在上传…重新上传取消

正在上传…重新上传取消

SimpleDateFormat 类作用

可以去完成日期时间的格式化操作

正在上传…重新上传取消

构造器

构造器 说明
public SimpleDateFormat(String pattern) 构造一个SimpleDateFormat,使用指定的格式

格式化方法

格式化方法 说明
public final String format(Date date) 将日期格式化成日期/时间字符串
public final String format(Object time) 将时间毫秒值式化成日期/时间字符串

正在上传…重新上传取消

SimpleDateFormat解析字符串时间成为日期对象

解析字符串时间成为日期对象: 2011-11-11 11:11:22 -> Date日期对象

package com.itheima.d2_simpledateformat;

import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatDemo1 {
//    SimpleDateFormatDemo1简单日期格式化类的使用
    //格式化时间 解析时间
public static void main(String[] args) {
    //1.日期对象
    Date d=new Date();
    System.out.println(d);
    //2.格式化这个日期对象(指定格式化形式)
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日  HH:mm:ss EEE a");
    //3.开始格式化日期对象成为喜欢的字符串形式
    String rs= sdf.format(d);
    System.out.println(rs);
    //4.格式化时间毫秒值.121秒后的时间
    long time1=System.currentTimeMillis()+121*1000;
    String rs2= sdf.format(time1);
    System.out.println(rs2);


    System.out.println(sdf.format(time1));
}
}
Mon Apr 11 14:46:36 CST 2022
2022年04月11日  14:46:36 周一 下午
2022年04月11日  14:48:37 周一 下午
2022年04月11日  14:48:37 周一 下午

案例

请计算出 2021年08月06日11点11分11秒,往后走2天14小时49分06秒后的时间是多少。

解析方法 说明
public Date **parse(String source)** 从给定字符串的开始解析文本以生成日期
package com.itheima.d2_simpledateformat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatDemo2 {
    public static void main(String[] args) throws ParseException {
        //目标:学会使用SimpleDateFormat解析字符串成为日期对象
        //请计算出 2021年08月06日11点11分11秒,往后走2天14小时49分06秒后的时间是多少。

        //1.把字符串拿到程序中来
        String datestr="2021年08月06日11:11:11";
        //2.把字符串时间解析成日期对象(重点):形式必须与被解析时间的形式完全一样,否则运行时解析报错。
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
        Date d=sdf.parse(datestr);
        //3.往后走
        long time=d.getTime()+(2L*24*60*60+14*60*60+49*60+6)*1000;
        //4.格式化这个时间毫秒值
        System.out.println(sdf.format(time));

    }
}

总结

1.SimleDateFormat可以格式化哪些时间形式,? Date日期对象,时间毫秒值。 2、SimpleDateFormat如何进行字符串时间的解析的? 通过一个方法: public Date parse(String source)

Test秒杀活动

需求 某购物网站举办秒杀活动,开始时间和结束时间如左图所示,当前活动结束后,系统记录到2位用户的付款时间分别如下: 小贾下单并付款的时间为:2020年11月11日 0:03:47 小皮下单并付款的时间为:2020年11月11日 0:10:11 规则:顾客的付款时间必须在秒杀时间之内,请判断出两位顾客是否秒杀成功。 分析 把4个字符串形式的时间解析成日期对象。 判断小贾和小皮的时间是否在秒杀时间范围之内,并给出相应的提示。

package com.itheima.d2_simpledateformat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatTest3 {
    public static void main(String[] args) throws ParseException {
        //1.开始时间和结束时间
        String startTime="2021-11-11 00:00:00";
        String endTime="2021-11-11 00:10:00";
        //2.小贾  小皮
        String xiaoJia="2021-11-11 0:03:47";
        String xiaoPi="2021-11-11 0:10:11";
        //3.解析他们的时间(否则计算机无法识别)
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1=sdf.parse(startTime);
        Date d2=sdf.parse(endTime);
        Date d3=sdf.parse(xiaoJia);
        Date d4=sdf.parse(xiaoPi);

        if(d3.after(d1)&&d3.before(d2)){
            System.out.println("小贾秒杀成功");
        }else {
            System.out.println("小贾秒杀失败");
        }

        if(d4.after(d1)&&d4.before(d2)){
            System.out.println("小皮秒杀成功");
        }else{
            System.out.println("小皮秒杀失败");
        }
    }
}

Calendar

Calendar概述

  • Calendar代表

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章