面向对象的内容:

类:  相同对象或者相同事物的一个公同特点的抽象。
     类只是一个概念一个描述。类可以认为是虚拟的,不是真实存在的。

对象(实例): 具体存在的一个对象,每个人都是一个对象,是人类的一个对象
                     对象是真实存在的,每个具体存在的事物都可被认为是对象。
                     对象也称之为实例。

2.类 定义类


[修饰符] class <类名称>{ 类:有且仅有5种成分。 
        // 成员变量(Field) 可以出现 0 ~N个
                // 构造器 可以出现 0 ~ N个 
                // 方法 可以出现 0 ~ N个 
                // 代码块 可以出现 0 ~ N个 
                // 内部类 可以出现 0 ~ N个
                }

修饰符: 省略,public、final|abstrac。
类名称:首字母大写,"驼峰模式"
类的成分:成员变量(Field),构造器,方法,代码块,内部类
类的作用:

1.定义成员变量 
2.定义方法 
3.定义构造器 
4.可以通过类的构造器创建对象 
5.调用static修饰的成员变量或者方法。
 6.类可以被继承-后面的内容

成员变量

 1、用来描述类的特征状态或者属性的变量。
 格式:[修饰符] <数据类型> 变量名称 [= 初始值];

修饰符: public|protected|不写|private、static、final
数据类型:基本数据类型和引用类型 变量名称: 合法的标识符,首字母一般小写,"驼峰模式",一般是名词

一般来说程序员只需要定义程序关心的成员变量(状态)即可.

 2、java中4中修饰符分别为public、protect、default、private,他们这就说明了面向对象的封装性,所以我们要适用他们尽可能的让权限降到最低,从而安全性提高。

    下面详细讲述下它们的访问权限问题。(同一个类中除内部类外所有修饰符都是可以访问的,所以下面排除这种情况。)

首先在这里把它们的访问权限表示出来:

访问权限 类 包 子类 其他包

public ∨ ∨ ∨ ∨

protected ∨ ∨ ∨ ×

default ∨ ∨ × ×

private ∨ × × ×

4.局部变量

5.方法

 用来描述类或者对象行为的。 

格式: [修饰符] <返回值> 方法名称(形参列表){ // 方法体 }

修饰符: public|protected|不写|private、static、final|abstract

 返回值:基本数据类型,引用类型, void(空:无返回值)

    方法名称 : 合法的标识符,首字母小写,"驼峰模式" ---> startSing(); 一般方法名称是一个动词

    形参列表: 格式 :  (类型 形参变量 , 类型 形参变量, 类型 形参变量 ,)

  注意事项:
      1.方法必须定义在类下面,不能放在其他地方 :因为方法是类的成分。
       2.如果方法申明了返回值类型,方法中必须存在有效的return语句。

6.方法详解 方法不能独立存在,方法属于类的成分,方法只能放在类下面

方法的形参列表用于接收传递过来的参数

 1.方法的参数传递机制:值传递   
      对于基本数据类型,就是将值传递给方法的形参
  对于引用类型的数据,只是将引用类型的地址复制一份传递给方法的形参
  java不是传递对象的,而是传递引用的。所以是值传递。

  2.形参可变的方法      
         可变形参格式: 类型...  变量

         [修饰符] <返回值> 方法名称(形参列表){
               // 方法体
          }

      可以传递任意多个对应类型的参数都可以。
      也可以直接传递一个对应类型的数组给方法。

      当有多个形参的时候,可变形参只能放在形参列表最后一个位置。

 3.方法的递归     
    递归算法是一种直接或间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是    十分有效的,它往往使算法的描述简洁而且易于理解。

   4.方法的重载 
    两同一不同。
     在同一个类中,方法名称相同,形参列表不同就是方法的重载。

    注意事项:
          1.形参列表相同,形参变量不同不算重载
        2.形参列表相同,返回值不同不算重载
       3.调用重载的方法,只能识别一个就算重载。

7.堆栈

 局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。 成员变量存储在堆中的对象里面,由垃圾回收器负责回收。

8.构造器

 构造器的作用:创建对象的,并且可以给对象实例化一些初始值。

格式:[修饰符] 类名称(形参列表){ // 执行代码 }

修饰符: public|protected|不写|private   

     类名称:必须是当前类的名称一字不差:大小写完全一致。

     形参列表: (类型 变量 ,类型 变量 , .....)

     注意点: 1.构造器的名称必须与类的名称一字不差:大小写完全一致
                   2.构造器与方法极为相似但是构造器没有返回值申明。
                    3.构造器也必须放到类下面,不能定义在其他成分中。
方法重载:(同一个类中,方法名称相同,形参列表不同)

构造器重载:(同一个类中,方法就是类名称,形参列表不同)

this(参数值列表):在同一个类的构造器中调用其他的构造器 
                 -- 具体调用哪个构造器根据参数值列表确定
                    -- this调用必须放在构造器的第一行!!!

9.创建对象

使用类的构造器创建对象 : new 构造器;

格式:类名 对象变量 = new 构造器;

 创建对象是通过new 构造器实现的:
 注意: 新建一个类默认就自带了一个无参数的构造器,程序员可以不写。
        但是如果从新定义了一个有参数的构造器那么默认的无参数的构造器就没有了
    此时,程序员应该将无参数的构造器自己定义出来。

10.static关键字

static修饰成员变量:那么这个成员变量就是静态成员变量,也就属于类的成员变量。 static修饰方法:那么这个方法就是静态方法,也就属于类的方法。

没有static修饰的成员变量,那么这个成员变量就是实例成员变量,属于对象(实例)的成员变量
  没有static修饰的方法,那么这个方法就是实例方法,属于对象(实例)的方法。

  补充:静态的成员变量和静态的方法其实通过对象也可以调用,但是不推荐
            非静态的成员变量以及方法只能通过对象来调用,不能通过类来调用

11.成员变量的访问

如果成员变量是被static修饰的,可以直接通过类来访问。 类名.静态成员变量名称

如果成员变量是没有被static修饰的,必须先有对象才可以访问该成员变量。
     类名 对象 = new 构造器;
 对象.实例成员变量 

   注意:1.对于静态成员变量,应该直接用类名来调用。 
             2.对象也可以访问静态的成员变量但是强烈不推荐使用对象来访问静态成员变量 
               --- 如果遇到面试题使用对象访问静态成员变量将对象换成类来解答。
              3.类是绝对不能直接访问实例成员变量的,实例成员变量必须先通过构造器创建对象再通过对象来访问。
             4.静态成员变量只会与类同时加载一次

             实例成员变量(没有用static修饰的成员变量),每次创建新的对象的时候,都会“复制”一份给这个对象。

12.调用方法

1.静态方法(有static修饰的方法) 调用格式:[返回类型 变量 = ] 类名.方法名(参数值); 当就在这个静态方法所在的类中调用次静态方法的时候,可以省略类名调用。 因为一旦不是用对象调用那么就是静态方法,JVM会自动帮你加上当前类名去调用。

2.实例方法(没有static修饰的方法) 
       创建对象:类名 对象变量 = new 构造器;
        调用格式:[返回类型 变量 = ] 对象变量.方法名(参数值);

13.this关键字

this:当前对象 this在实例方法中的时候:哪个对象调用这个方法,this就代表哪个对象。 this在方法中一般用于很方便的操作当前调用此方法的对象。

this在构造器中的时候:this就代表正在创建的那个对象 
       this在构造器中一般用于对当前创建的对象,进行初始值的设置。

       this是代表对象的,而静态方法被类直接调用.所以this不能出现在静态方法中。

14.方法的重载

在同一个类中,方法名称相同,形参列表不同就是方法的重载。

  注意事项:
       1.形参列表相同,形参变量不同不算重载

       2.形参列表相同,返回值不同不算重载

       3.调用重载的方法,只能识别一个就算重载。

15.变量

类变量(有static) ↗ 成员变量(定义在类中、保存堆中)
↗ ↘ 实例变量(无static) 变量 形参 ↘ ↗
局部变量(定义在方法中、保存栈中)→ 方法中定义的局部变量 ↘ 代码块定义的局部变量

注意: 
      1.成员变量可以不用定义初始值.初始值如果不申明就会采用默认的初始值
        所有的数值型都是:0 或者 0.0  字符型式空格符 
         boolean类型的默认值false , 引用类型都是null

      2.成员变量可以在当前类中的任何地方访问。
      3.静态成员变量与类同时加载一次,只会加载一次。实例成员变量跟对象有关,每次创建
      对象都会为对象分配实例变量

  静态成员变量生命周期是从:类开始加载执行到类执行完成才会释放。
    实例成员变量:对象如果存在实例变量就存在。

16.代码块

实例代码块 实例代码块 // 实例代码块 { // 执行代码 int a = 10 ; // 局部变量
int b = 11 ; System.out.println("-----------实例代码块----------------"+(a+b)); }

每次创建一个对象都会执行一次实例代码块 
    实际上底层是将实例化代码块中的代码依次复制到每一个构造器中了,所以每次创建对象都会执行一次实例代码块中的代码。
    一般可以将构造器中相同的代码提到一个实例化代码块中:这样可以提高代码的复用。
  静态代码块
        // 静态代码块  :类一加载就会立即执行静态代码块。类加载一次,所以静态代码块只会执行一次。
     // 优先执行
      static{
            // 执行代码 
            int a = 10 ;  // 局部变量  
            int b = 1  ;
            System.out.println("-------------static代码块----------------"+(a+b));
    }

17.包

包的作用:

为了区别类,一般要使当前定义的类在全世界是唯一的。

为了当命令相同的java文件名的时候不至于冲突,这个时候就需要引入包。

不同的类可以拥有不同的包。

包:可以用于项目分层设计。
包名称的来源: 公司域名(http://www.fkjava.org) ---- 域名的倒写作为包 -----> org.fkjava.项目名称

给类定义包:
      格式: package 包名称 ; 
       一般放在类文件的第一行。

  注意: 1.如果一个类指定了包, 那么也应该将类文件放到当前包下面编辑,编译以后的

             class文件是一定要放到对应包下面。

               2.一旦类申明了包,那么调用类的时候的完整格式应该是
                      类的全限名:包名称.类名
方便的使用类:导包 import 包名称.类名称; 接下来就可以直接使用类。 import 包名称.*; 就可以导入包下所有的类。

注意点: 1个类只能定义一个包  package 包名;
                 package 包名; 0~1

   1个类可以导入很多的包 
              import 包名; 0~N ;

   java.lang下的类不用导包

18.封装、继承、多态

面向对象的3大特征: 封装、继承、多态

--- 封装:

类的设计:要把该隐藏的部分隐藏起来;要把用户操作接口暴露出来。 ——封装
            合理隐藏、合理暴露。

 一般来说:成员变量隐藏(有些常量也会暴露);方法暴露(有些特殊工具方法也会隐藏)

 Java是提供了3个修饰符(4个权限)来控制隐藏和暴露(封装)

 private    :它修饰的方法、成员变量只能在该类里中被访问。 彻底隐藏
 不写        :它修饰的方法、成员变量只能在该类、该类所在同一个包中被访问。 部分隐藏、包访问权限
 protected  :它修饰的方法、成员变量可以在该类、该类所在同一个包、该类子类中被访问。 部分暴露、子类访问权限
 public     :它修饰的方法、成员变量可以任意地方被访问。 彻底暴露、公开权限

                     private       不写          protected        public
  当前类               √           √               √                      √
  同一个包            ×           √               √                      √
  当前类的子类      ×           ×               √                     √
  任意地方            ×           ×               ×                      √

  注意:
        一般来说:成员变量应该隐藏(有些常量也会暴露);方法应该暴露(有些特殊工具方法也会隐藏)

        一般对成员变量进行隐藏, 但是会提供一套getter和setter方法来操作成员变量使其合理暴露。
-- 继承:

代码复用的一种方式。

     People                      Student  / Teacher
  父类(超类、基类):大类;  子类(派生类):小类

  1. 语法格式:
       类 extends 类(只能有一个)
   一个类可以拥有多个子类或者没有子类。一个类只能继承一个父类
   java是单继承:一个类只能继承一个直接父类。

   继承父类以后就可以获得父类的所有成员变量和方法。
       子类只是拥有了父类的成员变量和方法,但是依然只能访问有修饰权限的成员变量或者方法
   有时候父类的方法会申明成protected,protected修饰的成员子类可以直接访问。

   一般来说子类是优于父类的,因为子类不仅获得父类的成员变量和方法,而且子类自己还可以扩展。
    a.    1.概念子类继承父类获取父类的成员变量和方法

     2.java是单继承的,一个类只能继承一个直接父类。

    注意: 当一个没有继承另一个类的时候默认就会继承一个Object类,但是可以省略写继承Object,默认会加上去。
           当一个类继承了其他类它就不直接继承Object但是一定会间接继承了Object
        Object是一切的类的直接父类或者一定是间接父类.

    类的修结构:[修饰符] class <类名称> [extends Object] {

            }
方法重载(在同一个类中): 两同一不同 同一个类,方法名相同 形参不同

方法重写(子类对父类中的方法进行重写): 两同两小一大

b. 方法重写

@Override
    方法重写:子类认为从父类那里继承得到的方法不适合时或者认为不满足自己的需求,
                    子类可以重写父类的方法。一般重写的实例方法,静态方法没有重写的概念

   所谓重写,就是子类重新定义从父类得到的方法。

             方法重写:2同2小1大。
               2同:方法名要相同,形参列表相同。
               2小:返回值类型要相同或更小(子类)相同类型 是继承关系中的大小;
                       声明抛出的异常相同或更小;
               1大:方法的访问权限相同或更大。

         可以通过@Override来标记次方法一定需要是重写的方法,如果不是重写的就会报错

    不加@Override:方法有可能不是重写的也可能是重写的方法
                  如果是重写的方法必须合法,如果不是重写的方法
                   就是一个普通的方法

        所以建议子类在重写父类的方法的时候应该加上@Override 。

        方法重写与方法重载: 
         不同点: 
              方法重写是在子类和父类之间的操作,重写的方法在子类中。
          方法重载是在同一个类中

          方法重写中重写的方法必须与父类被重写的方法的形参列表完全一致。
          方法重载重载的方法形参列表必须不一样。

          方法重写重写的方法的访问权限必须与父类相同或者更大
          方法重载的权限无所有。

          方法重写的返回值类型必须与父类被重写的方法的返回值类型相同或者更小
          方法重载无所谓返回值类型。

         相同点: 
              方法重写的方法名必须与父类被重写的方法的方法名称相同
              重载的方法的方法名称也是一样必须相同

c、super:  
      super限定,用于访问父类的成员(成员变量和方法)。
      super.成员
  super不能直接出现在静态方法中来访问父类的成员
  可以在子类的对象方法中通过super访问父类的成员。
d. 子类调用父类的构造器

【死规则】: 子类构造器一定会调用父类的构造器一次(有且仅有一次)

     - 子类构造器没有显式调用父类构造器,
       子类构造器会默认调用父类的无参数的构造器。

   子类构造器之所以一定会调用父类的构造器是因为子类构造器中
   存在一个super()调用:这个默认的super()调用会先调用父类的无参数构造器。

     - 子类构造器显式用super调用来调用父类指定的构造器。
        super调用: super(参数)
        super调用 - 调用父类的构造器。只能在构造器的第一行。
        super(参数)  - 到底调用哪个构造器,取决你传入的参数
        super()调用  this()调用不允许同时出现:因为this()和super()都只能放在第一行。
--- 多态

多态:多个相同类型的变量,调用同一个方法,表现出多种不同的行为特征,这就叫多态。

   在继承关系中也存在类型转换.
   子类是小类  父类是大类 
   子类可以自动转换到父类:向上转型

   多态的原因:变量在调用方法的时候,实际上是找到变量真正指向的对象所拥有的该方法来执行。

   继承中的类型转换:  
         子类是小类  父类是大类 
         子类可以自动转换到父类:向上转型
     父类转换到子类 : 需要强转,而且执行的时候必须是同一个对象才可以强转成功

   java的类型分为编译时类型和运行时类型:
       编译时类型: 只是在写代码到javac编译的这个过程中的类型。
       运行时类型: 在java命令执行的时候,真正指向的对象类型。

        父类转换到子类 : 需要强转,编译时的时候是不会报错的。
           但是在运行的时候,强转以后的实际的对象与对应变量类型必须一致。
           否则会出现很经典的错误:ClassCastException(类转换异常)

19.垃圾回收机制

java会自动回收没有被引用的对象 ,不需要程序员去维护垃圾的回收。 

20.final关键字

 修饰符: 不写 , private,public protected , static | final 类只能用public,final或者不写。

final可以修饰变量(成员变量和局部变量)、方法、类。

 【总规则】:final可以修饰变量:表示该变量被赋初始值之后,该变量不能被重新赋值
          final修饰的变量只能赋值一次

   final修饰的成员变量必须赋值,有且只能赋值一次!!!

 ▲ final修饰的成员变量:final修饰成员变量,必须有程序员显式指定初始值。

    final修饰的实例变量,一共可在3个地方指定初始值(只能指定一次):
     A - 定义时指定初始值。
     B - 在实例初始化块中指定初始值。 {  }
     C - 在构造器中指定。如果在构造器中为final实例变量指定初始值,必须每个构造器中都要指定。
     表面上看,有3个地方,其实最终都会还原到构造器中执行。
 --- 对象的final修饰的成员变量只能赋值一次

    final修饰static的静态变量,一共可在2个地方指定初始值(只能指定一次):

     A - 定义时指定初始值。
     B - 在类初始化块中指定初始值。   static{   }

▲ final修饰的局部变量

不管是否有final修饰,在使用之前一定要给初始化值。

    final修饰局部变量之后,final局部变量只能被赋值一次。

final变量,用于保护该变量的值,无论程序如何改变,该变量始终都是最初的值,永远只能赋值一次。
▲ final修饰方法

表明该方法不能被重写。@Override
   重写规则:2同2小1大。

   final方法,用于保护该方法,防止被子类去重写(覆盖)

   private与final同时修饰方法完全没有意义的,但Java编译器却允许你这么干,这就是当年Java设计者留下的缺陷。
▲ final修饰类:

表明该类不能被继承。

   final类,用于保护该类,防止用于去派生子类。

  Java的String、System、Math等大量的类都是final类。
  反过来,如果给Object类加上final,整个Java体系就崩塌了。

21.toString 和equals(Object object)方法

一切类都是Object的子类 , toString()方法和equals(Object obj) 方法是Object类中的方法 所以所有的类都拥有了toString()方法和equals(Object obj) 方法 。

1.toString()方法 

   返回该对象的字符串表示,就是返回该对象的 名称@hashcode 值。

   直接输出对象实际上是对象调用了toString()方法来打出对象的值:对象类名@hashcode  hashcode相当于对象在内存中的地址
   但是toString()可以省略。

   toString()方法是Object的
   如果不重写toString()方法,那么是直接调用Object的toString()打出对象地址。
   toString()方法存在的意义就是为了被子类重写。
   重写出来一般用于打出对象的具体内容,如下:
   @Override
       public String toString(){
    // 可以打出对象的内容
    return "User[name="+this.name+",age="+this.age+",passWord="+this.passWord+"]"; 

       那么以后再输出对象的时候,对象就会调用自己重写的toString()方法来打出自己的内容
   当然,toString()的调用默认可以省略不写,会自动调用。

2. equals(Object obj)方法  

  == :在引用类型中:如果用来判断两个变量是否==,那么这两个变量指向的必须是同一个对象才算相等。
        如果指向的是不同的对象就不相等。

  equals:Object提供的equals方法的默认的作用就和==的效果是一样的:用来判断两个对象是否相等
    必须是同一个对象才是true。

  equals存在的意义就是为了让子类来重写的。
     重写以后可以自己制定对象的比较规则,从而使对象之间的比较判断规则更加贴切的满足业务需求。
  --------------------------------------------------------------------------------------------
  intanceof格式:用来判断对象是否属于某个类型
        对象 instanceof 类型 : 判断对象是否是这个类型的对象。

22.abstract abstract :抽象(抽象类、抽象方法)

修饰符(访问权限修饰符):不写,public,private,protected 
 静态修饰符: static 
 保护修饰符: final 

  备注:非抽象类中不能定义抽象方法
          抽象类中可以定义抽象方法,不写抽象方法也可以
          抽象类主要用于被继承,因为抽象不能用于创建对象

 abstract只能修饰类或方法。抽象类、抽象方法。
 abstract与final是互斥:两个不能同时修饰一个成员:
    --  abstract修饰类和方法就是为了被继承和重写
     --  final修饰类和方法 就是为了避免被继承以及被重写。

 ▲ 抽象方法:
      格式:[修饰符] abstract 返回值 方法名(形参列表);

    - 抽象方法不能定义方法体。
    - 抽象方法必须使用abstract修饰

     注意:
     如果一个类拥有了抽象方法,这个类就必须定义成抽象类
 抽象类就相当于一个模板,就是为了被继承!!!

 ▲ 抽象类的特征: 有得有失。
     除了这4个字之外,抽象类与普通类完全一样的。
     有得:抽象类得到新功能:可以拥有抽象方法。
     有失:抽象类失去了:创建对象的能力。

 ▲ 抽象类的作用:
    - 被继承
    - 定义变量 
    - 调用类方法或访问类变量。
    - 派生子类 - 要求抽象类必须有构造器。

    抽象类相当于定义一个“模板”,用于被子类去继承。

一个类如果继承了抽象类  如果这个类不处理继承的抽象方法 那么他自己也必须成为抽象类
一个类如果继承了抽象类  如果希望成为实现类 那么他就必须重写抽象类中所有的抽象方法

    子类继承抽象父类,要么子类重写父类所有的抽象方法;
                     要么子类也只能是抽象的。

    抽象类的意义:抽象父类它只定义一些模板,这些模板相当于是子类一般都会有的
               但是抽象类它不清楚具体的行为是什么样子,只是设计了这样一个模板。
           然后交给子类去继承,子类拿到模板去丰富自己的行为

    抽象类在编程中的好处: 模板集中管理,提高代码的复用

    模板模式。

23.接口(interface) 接口和抽象类都是一种特殊的类。

接口 : 相当于一种彻底抽象的类。

  ▲ 接口的语法:

  [修饰符]  interface <接口名> extends 父接口1,父借口2,......
  {
        // 0到多个常量定义。 不管你写还是不写,都有public static final修饰。
        // 0到多个抽象方法定义、Java 8支持default、static方法(都可有方法体)定义
        // 0到多个内部类等

  }

  ▲ implements
  接口是用来被实现的:一个类可以通过implements来实现接口
  当一个类实现了某个接口就必须将接口中的抽象方法全部重写
  接口中的抽象方法可以只定义方法签名,也可以使用abstract修饰

  一个类只能有一个直接父类,但是可以实现多个接口

24.内部类

Java类的5大成分: 成员变量、方法、构造器、代码块、内部类

内部类:直接放在另一个类的类体中定义。
          内部类可以提供更加好的封装。

 外部类(宿主类)
 内部类(嵌套类、寄生类)

  为什么要定义内部类?内部类的便捷之处?

    1. 内部类可以提供更好的封装。
       内部类在外部类中可使用private、protected、public修饰,因此可以更好地进行封装。

    2. 内部类可以直接访问外部类的成员,即使是外部类的private成员。
       静态内部类(类成员)不允许直接访问外部类的实例成员。

       当内部类的实例变量名与外部类的实例变量名冲突时。
       要显式添加   外部类.this. 来限定访问外部类的实例变量

 ★ 内部类与外部类的语法上区别:

  - 外部类只能使用 ,不写,public、final|abstract。
     内部类可以使用private|protected|public、static、final|abstract修饰,

  - 非静态内部类不允许拥有静态成员,除非静态成员变量,且使用final修饰,且指定了初始值。

  -  静态内部类不允许直接访问外部类的实例成员

▲ 使用静态内部类

        静态内部类的实例,必须寄生在外部类的类本身里 
        在外部类以外的地方使用静态内部类:
        外部类.内部类  —— 相当于外部类是内部类的一个包名。
    再通过内部类对象就可以操作内部类的成员。

▲ 使用非静态内部类 - 【难理解,仅供参考】

        【总原则】:非静态内部类的实例,必须寄生在外部类的实例里 
                    ——如果没有外部类的实例,不可能有非静态内部类实例。

        ◆ 使用非静态内部类定义变量:
            外部类.内部类 变量名;

        ◆ 使用非静态内部类创建实例
            宿主.new 非静态内部类构造器();
匿名内部类 : 针对于接口和抽象类

    格式:直接在类中
     new 接口|抽象类(){
    // 必须重写所有的抽象方法
     }

    匿名内部类不能复用。
     匿名内部类必须重写所有的抽象方法

25.Lambda表达式

java8以后的新技术:“Lambda 表达式”(lambda expression)是一个匿名函数

就是可以以一种简化的方式来创建匿名内部类

   函数式接口中只能定义一个抽象方法!
   接口类型 接口=()->{
   }

   函数式接口可以使用注解:@FunctionalInterface 来标记接口
   一旦这个接口有多个抽象方法编译就报错。

26.正则表达式

正则表达式:用于校验数据的格式是否正确

// 定义一个正则表达式 
    String regex = "[abc中]";
   String regex1 = "[^abc中]";
    String regex2 = "[a-z]";
    String regex3 = "[A-Za-z3-9]";
    String regex4 = "[9[0-7]]";
    String regex5 = "ab";
    String regex6 = ".";  // 任何字符
    //matches(String regex) 
    //  告知此字符串是否匹配给定的正则表达式。
    System.out.println("国".matches(regex));   
    System.out.println("中".matches(regex1));  
    System.out.println("ab".matches(regex2));  
    System.out.println("a".matches(regex2));   
    System.out.println("3".matches(regex3)); 
    System.out.println("8".matches(regex4)); 
    System.out.println("ab".matches(regex5));  // true 一定要一样类似于equals判断
    System.out.println("在".matches(regex6));
    System.out.println("9".matches("\\d"));

    System.out.println("到".matches("\\D"));
    System.out.println(" ".matches("\\s")); // 空格字符  true
    System.out.println(" ".matches("\\S")); // 非空格字符 false
    System.out.println("$".matches("\\w")); // [a-zA-Z_0-9] 
    System.out.println("在".matches("\\W")); 

    System.out.println("aabcbcbca".matches("[abc]*")); 
    System.out.println("042424".matches("[0-9]+")); 
    System.out.println("af43".matches("\\w{4}")); 
    System.out.println("admi2n".matches("\\w{6,10}"));
String str = "(总部)地址dsfdvvv:北京市东城区东luochunlong@163.com中街32号楼7层(东环广场对面)邮编:100027 " + "电话:1010-3721,400-610-3721 ,传真:010-64170018 手机号码:13360026135,15800000653 邮件:webmaster@piao.com.cn(网络部)" + "kebi@piao.com.cn (客服部)ligang@damai.cn (市场部)" ;

// 定义一个电话号码正则表达式 
    String telRegex = "1[34578]\\d{9}";
    String emailRegex = "\\w{1,20}@\\w{2,10}(\\.\\w{2,10}){1,2}";  //  java 

    // 1.将正则表达式编译成java代码中的对象Pattern
    Pattern p = Pattern.compile(emailRegex);
    // 2.再通过正则表达式获取一个匹配器
    Matcher m = p.matcher(str);
    // 3.开始拿着匹配器去内容中匹配出满足正则表达式条件的内容
    while(m.find()){
         System.out.println(m.group()) ; // 拿到正则表达式匹配的完整内容
         //System.out.println(m.group(1)); //    拿到正则表达式的第一个括号匹配对应的内容
    }