JAVA SE — Day 13

目 录

第1章 final 关键字
1.1 final 的概念
1.2 final 的特点
第2章 static 关键字
2.1 static的概念
2.2 static 的特点
2.3 static注意事项
2.4 定义静态常量
第3章 匿名对象
3.1 匿名对象的概念
3.2 匿名对象的特点
第4章 内部类
4.1 内部类概念
4.2 成员内部类
4.3 局部内部类
4.4 内部类的实际使用
4.4.1 匿名内部类概念
4.4.2 匿名内部类调用多种方法
第5章 包的声明与访问
5.1 包的概念
5.2 包的声明格式
5.3 包的访问
5.4 import 导包
第6章 访问修饰符
第7章 代码块
7.1 局部代码块
7.2 构造代码块
7.3 静态代码块
7.4 同步代码块

第1章 final 关键字

1.1 final 的概念

继承的出现提高了代码的复用性,并方便开发。但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写。
可是当子类继承了这些特殊类之后,就可以对其中的方法进行重写,此时就需要使用到一个关键字final,final的意思为最终,不可变。

  • final是个修饰符,它可以用来修饰类,类的成员,以及局部变量。
1.2 final 的特点

1)final 修饰类

  • final修饰类不可以被继承,但是可以继承其他类。
    • 案例
      class Yy {}
      final class Fu extends Yy{} //可以继承Yy类
      class Zi extends Fu{} //不能继承Fu类

2) final修饰方法

  • 父类中final修饰的方法,子类可以直接调用,但不可以被子类重写。
  • 但父类中没有被final修饰方法,子类覆盖后可以加final。
    • 案例
      class Fu {
      // final修饰的方法,不可以被覆盖,但可以继承使用
      public final void method1(){}
      public void method2(){}
      }
      class Zi extends Fu {
      //重写method1方法,会报错
      //重写method2方法
      public final void method2(){}
      }

3) 修饰局部变量

① 修饰基本数据类型变量

  • 修饰的变量称为常量,这些变量只能赋值一次
    • 案例
      final int i = 20;
      i = 30; //赋值报错,final修饰的变量只能赋值一次

② 修饰引用数据类型

  • 引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改

    • 案例
      final Person p = new Person();
      Person p2 = new Person();
      p = p2; //final修饰的变量p,所记录的地址值不能改变
      p.name = “小明”;//可以更改p对象中name属性值
      p不能为别的对象,而p对象中的name或age属性值可更改。

4) 修饰成员变量

  • 只能赋值一次
  • 成员变量在堆内存中有默认值,但final修饰的成员变量固定的不是默认值而是手动赋的值。
  • 成员变量的赋值,有两种实现方式:①直接=赋值②用构造方法赋值
  • 修饰成员变量,需要在创建对象前赋值,否则报错。(当没有显式赋值时,多个构造方法的均需要为其赋值。)

    • 案例
      class Demo {
      //直接赋值
      final int m = 100;
      //final修饰的成员变量,需要在创建对象前赋值,否则报错。
      final int n;
      public Demo(){
      //可以在创建对象时所调用的构造方法中,为变量n赋值,是在建造对象的同时调用,所以可以执行
      n = 2016;
      }
      //不能用set方法,因为set是建完对象之后才能调用,final修饰的成员变量,需要在创建对象前赋值。
      final int age;
      public void setAge(int age){
      this.age= age;
      } //用set方法赋值则会报错
      }

第2章 static 关键字

2.1 static的概念
  • static它是静态修饰符,被static静态修饰的数据不再属于对象的特有内容,而是共享内容。
  • 举例:
    这里写图片描述
2.2 static 的特点

1)对象的共享数据

  • 被static修饰的成员变量属于类,不属于这个类的某个对象。
    (也就是说,多个对象在访问或修改static修饰的成员变量时,其中一个对象将static成员变量值进行了修改,其他对象中的static成员变量值跟着改变,即多个对象共享同一个static成员变量)
    • 案例:
public class Person {
   String name;
   static  String className ;
}
public class Test {
    public static void main(String[] args) {
        Person  p1 = new Person();
        Person  p2 = new Person();

        p1.name = "嘻嘻";
        System.out.println(p1.name);//输出结果为:嘻嘻
        System.out.println(p2.name);//输出结果为:null

        //对象调用类的静态成员变量
        p1.className = "基础班";
        System.out.println(p2.className);//输出结果为:基础班
    }
}

2)被静态修饰的成员,可以被类名直接调用

* 案例:
public class Person {
   String name;
   static  String className ;
}
public class Test1 {
    public static void main(String[] args) {
        System.out.println(Person.className);//输出结果为:null
        Person  p1 = new Person();
        p1.className = "基础班";
        System.out.println(Person.className);//输出结果为:基础班
    }
}
2.3 static注意事项

这里写图片描述
1) 静态不能直接调用非静态

  • 静态优先于非静态存在于内存之中,也就是说,静态存在的时候,还没有非静态的数据,所以无法调用还不存在的数据
    这里写图片描述
    这里写图片描述
    2) 非静态可以调用静态
    这里写图片描述

3)静态中不能写this和super,否则报错
4) 被static修饰的成员可以并且建议通过类名直接访问。

  • 访问静态成员的格式:
    类名.静态成员变量名
    类名.静态成员方法名(参数)
    对象名.静态成员变量名 ——不建议使用该方式,会出现警告
    对象名.静态成员方法名(参数) ——不建议使用该方式,会出现警告

    *代码演示
    class Demo {
    //静态成员变量
    public static int num = 100;
    //静态方法
    public static void method(){
    System.out.println(“静态方法”);
    }
    }
    class Test {
    public static void main(String[] args) {
    System.out.println(Demo.num);
    Demo.method();
    }
    }

5)使用场景

  • static可以修饰成员变量和成员方法。
    • 什么时候使用static修饰成员变量?
      加static修饰成员的时候,这个成员会被类的所有对象所共享。一般我们把共性数据定义为静态的变量
    • 什么时候使用static修饰成员方法?
      方法该不该加静态是以方法中的成员变量作为衡量标准。如果方法中引用的成员都是静态变量或者引用的都是非成员变量,则需要声明为静态的方法;如果引用的成员中有非静态成员变量,则不需要加静态。

6)多态中的静态调用

  • 多态调用中

    • 编译都看父类,等号左边的父类,父类有则编译成功,父类没有则编译失败。
    • 运行,如果是静态方法,则运行父类的静态方法;非静态方法,则运行子类的重写方法
    • 成员变量,编译运行都看父类

    • 案例:
      父类:

public class Fu {
      static   int i  = 1 ;

      public static void show(){
          System.out.println("父类静态方法show");
      } 
}

子类:

public class Zi extends Fu{
     static   int i  = 1 ;

     public static void show(){
      System.out.println("子类静态方法show");
     } 
}

测试类:

/*
 * 多态调用中
 *
 * 编译都看父类,等号左边的父类,父类有则编译成功,父类没有则编译失败。
 * 运行,如果是静态方法,则运行父类的静态方法
 *          非静态方法,则运行子类的重写方法
 * 
 *  成员变量,编译运行都看父类
 */
public class Test {
   public static void main(String[] args) {
        Fu f = new Zi ();
        System.out.println(f.i);//输出结果为:1   成员变量看父类
        f.show();//调用父类的静态方法
   }
}
2.4 定义静态常量

1)静态常量

  • 开发中,我们想在类中定义一个静态常量,通常使用public static final修饰的变量来完成定义。
  • 此时变量名用全部大写,多个单词使用下划线连接。

2) 定义格式:

  • public static final 数据类型 变量名 = 值;

    • 举例:
      class Company {
      public static final String COMPANY_NAME = “传智播客”;
      public static void method(){
      System.out.println(“一个静态方法”);
      }
      }
  • 当我们想使用类的静态成员时,不需要创建对象,直接使用类名来访问即可。
    System.out.println(Company.COMPANY_NAME); //打印传智播客
    Company.method(); // 调用一个静态方法

4)注意:

  • 接口中的每个成员变量都默认使用public static final修饰。
  • 所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
    interface Inter {
    public static final int COUNT = 100;
    }
    访问接口中的静态变量
    Inter.COUNT

第3章 匿名对象

3.1 匿名对象的概念
  • 匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。

    • B:案例
      public class Person{
      public void eat(){
      System.out.println();
      }
      }

      创建一个普通对象
      Person p = new Person();
      创建一个匿名对象
      new Person();

3.2 匿名对象的特点

1)创建匿名对象直接使用,没有变量名。
new Person().eat() //eat方法被一个没有名字的Person对象调用了。

2)匿名对象在没有指定其引用变量时,只能使用一次。
new Person().eat(); 创建一个匿名对象,调用eat方法
new Person().eat(); 想再次调用eat方法,又重新创建了一个匿名对象

3)匿名对象可以作为方法接收的参数、方法返回值使用

        class Demo {
            public static Person getPerson(){
                //普通方式
                //Person p = new Person();  
                //return p;

                //匿名对象作为方法返回值
                return new Person(); 
            }

            public static void method(Person p){}
        }

        class Test {
            public static void main(String[] args) {
                //调用getPerson方法,得到一个Person对象
                Person person = Demo.getPerson();

                //调用method方法
                Demo.method(person);
                //匿名对象作为方法接收的参数
                Demo.method(new Person());
            }
        }

第4章 内部类

4.1 内部类概念
  • 将类写在其他类的内部,可以写在其他类的成员位置和局部位置,这时写在其他类内部的类就称为内部类。 其他类也称为外部类。
  • 什么时候使用内部类:
    • 在描述事物时,若一个事物内部还包含其他可能包含的事物,比如在描述汽车时,汽车中还包含这发动机,
      这时发动机就可以使用内部类来描述。
      class 汽车 { //外部类
      class 发动机 { //内部类
      }
      }
  • 内部类的分类
    • 内部类分为成员内部类与局部内部类。
      我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符、继承与实现关系等。在内部类中可以直接访问外部类的所有成员。
4.2 成员内部类

1)定义格式

  • 成员内部类,定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问
    • 格式:
      class 外部类 {
      修饰符 class 内部类 {
      //其他代码
      }
      }

2)访问方式

  • 内部类可以直接调用外部成员变量
  • 外部类调用内部类成员变量需要新建内部类对象:外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

    • 成员内部类代码演示:
      定义类:
      class Body {//外部类,身体
      private boolean life= true; //生命状态
      public class Heart { //内部类,心脏
      public void jump() {
      System.out.println(“心脏噗通噗通的跳”)
      System.out.println(“生命状态” + life); //访问外部类成员变量
      }
      }
      }

    访问内部类:
    public static void main(String[] args) {
    //创建内部类对象
    Body.Heart bh = new Body().new Heart();
    //调用内部类中的方法
    bh.jump();
    }

3)成员内部类的同名变量调用

  • ① 内部就近法原则

定义类:

public class Outer {
    int i  = 1;
    class Inner {
        int i  = 2;
        public void inner(){
            int i = 3;
            System.out.println(i);
        }
    }
}

测试类:

public class Test {
      public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
        in.inner();//输出结果为:3
    }
}
  • ② this. 变量名:调用内部类成员变量
    定义类:
public class Outer {
    int i  = 1;
    class Inner {
        int i  = 2;
        public void inner(){
            int i = 3;
            System.out.println(this.i);
        }
    }
}

测试类:

public class Test {
      public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
        in.inner();//输出结果为:2
    }
}
  • ③ 外部类.this.变量名:调用外部类成员变量
    定义类:
public class Outer {
    int i  = 1;
    class Inner {
        int i  = 2;
        public void inner(){
            int i = 3;
            System.out.println(Outer.this.i);
        }
    }
}

测试类:

public class Test {
      public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
        in.inner();//输出结果为:1
    }
}
4.3 局部内部类
  • 概念:局部内部类,定义在外部类方法中的局部位置,即定义在外部类的方法中的局部类。与访问方法中的局部变量相似,可通过调用方法进行访问。
  • 定义格式
    class 外部类 {
    修饰符 返回值类型 方法名(参数) {
    class 内部类 {
    //其他代码
    }
    }
    }
  • 访问方式:在外部类方法中,创建内部类对象,进行访问
  • 代码演示:
    定义类:
  /*
 * 将一个类,定义在方法中
 */
public class Outer {

    public void out(){

        class Inner {
          public void inner(){
            System.out.println("局部内部类方法");
          }
        }
        Inner in = new Inner();
        in.inner();
    }
}

测试类:

public class Test {
     public static void main(String[] args) {
        //调用局部内部类的方法inner
         new Outer().out();//输出结果为:局部内部类方法
    }
}
4.4 内部类的实际使用
4.4.1 匿名内部类概念

1) 概述

  • 内部类是为了应对更为复杂的类间关系。查看源代码中会涉及到,而在日常业务中很难遇到,这里不做赘述。
    最常用到的内部类就是匿名内部类,它是局部内部类的一种。
  • 定义的匿名内部类有两个含义:
    ① 临时定义某一指定类型的子类
    ② 定义后即刻创建刚刚定义的这个子类的对象

2)本质

  • 匿名内部类的本质是一个实现了接口或继承了某个类的子类匿名对象。
  • 即将实现类,实现接口,重写抽象方法,创建实现类对象调用方法等代码合为一步完成。
  • 匿名内部类只能写在方法之中。

3) 举例:
定义类:

public interface Smoking {
     public  abstract void smoking();
     /*
      * 实现类,实现接口,重写抽象方法,创建实现类对象调用方法
      * 
      * class XXX implement是 Smoking{
      *     public void smoking(){
      *     
      *     }
      * }
      * 调用时:
      * XXX  x = new XXX();
      * x.smoking();
      * 或者多态调用:
      * Smoking s = new XXX();
      * s.smoking();
      * 
      * 匿名内部类,简化代码,将以上代码合为一步完成。
      */
}

测试类:

public class Test {
   public static void main(String[] args) {
    //使用匿名内部类简化代码,将实现类,实现接口,重写抽象方法,创建实现类对象调用方法等代码合为一步完成。
    /*
     * 格式:
     *     new 接口/父类(){
     *       重写抽象方法
     *     };相当于子类对象
     * 子类对象.方法名→即可调用方法
     */
      new Smoking() {
          public void smoking() {
              System.out.println("人在吸烟"); 
          } 
      }.smoking() ;//输出结果为:人在吸烟
   }
}
4.4.2 匿名内部类调用多种方法

1)利用多态性,父类 引用 = 子类的对象→可以使匿名内部类同时调用多个方法。

 new 接口/父类(){
     *       重写抽象方法
     *     };
  • 以上相当于子类的对象,所以利用多态的特性可以实现匿名内部类调用多种方法。
    2)举例:
    定义类:
public abstract class Animal {
    public abstract  void eat();
    public abstract  void sleep();
}

测试类:

/*
 * public static void main(String[] args) {

         new  Animal() {
            public void eat() {
                 System.out.println("在吃饭");
            }
            public void sleep() {
             System.out.println("在睡觉");
        }
        };
 * 以上代码就是Animal的子类对象
 * 利用多态性,父类引用 = 子类的对象  可以同时调用两个方法
 */
public class Test {
     public static void main(String[] args) {

         Animal a = new  Animal() {
            public void eat() {
                 System.out.println("在吃饭");
            }
            public void sleep() {
             System.out.println("在睡觉");
        }
        };
        a.eat();// 输出结果:在吃饭
        a.sleep();// 输出结果:在睡觉
    }
}

第5章 包的声明与访问

5.1 包的概念
  • java的包,其实就是我们电脑系统中的文件夹,包里存放的是类文件。当类文件很多的时候,通常我们会采用多个包进行存放管理他们,这种方式称为分包管理。
  • 在项目中,我们将相同功能的类放到一个包中,方便管理。并且日常项目的分工也是以包作为边界。
  • 类中声明的包必须与实际class文件所在的文件夹情况相一致,即类声明在a包下,则生成的.class文件必须在a文件夹下,否则,程序运行时会找不到类。
5.2 包的声明格式
  • 通常使用公司网址反写,可以有多层包,包名采用全部小写字母,多层包之间用”.”连接类中包的声明格式: package 包名.包名.包名…;
    如:黑马程序员网址itheima.com那么网址反写就为com.itheima
  • 注意:声明包的语句,必须写在程序有效代码的第一行(注释不算)

    • 代码演示:
      package cn.itcast; //包的声明,必须在有效代码的第一行

      import java.util.Scanner;
      import java.util.Random;

      public class Demo {}
      ….

5.3 包的访问
  • 在访问类时,为了能够找到该类,必须使用含有包名的类全名(包名.类名)。包名.包名….类名
    • 如: java.util.Scanner
      java.util.Random
  • 带有包的类,创建对象格式:包名.类名 变量名 = new包名.类名();
    cn.itcast.Demo d = new cn.itcast.Demo();
    前提:包的访问与访问权限密切相关,这里以一般情况来说,即类用public修饰的情况。

  • 当我们要使用一个类时,这个类与当前程序在同一个包中(即同一个文件夹中),或者这个类是java.lang包中的类时通常可以省略掉包名,直接使用该类。

    • 如:cn.itcast包中有两个类,PersonTest类,与Person类。在PersonTest类中访问Person类时,可以省略包名,直接通过类名访问 Person。
      类名 变量名 = new类名();
      Person p = new Person();
  • 当我们要使用的类,与当前程序不在同一个包中(即不同文件夹中),要访问的类必须用public修饰才可访问。
    package cn.itcst02;
    public class Person {}

5.4 import 导包
  • 通过import导包的方式来简化,可以避免使用全类名编写(即,包类.类名)。
    导包的格式:
    import 包名.类名;

  • 当程序导入指定的包后,使用类时,就可以简化了。演示如下

    //导入包前的方式
    //创建对象
    java.util.Random r1 = new java.util.Random();
    java.util.Random r2 = new java.util.Random();
    java.util.Scanner sc1 = new java.util.Scanner(System.in);
    java.util.Scanner sc2 = new java.util.Scanner(System.in);
    
    //导入包后的方式
    import java.util.Random;
    import java.util.Scanner;
    //创建对象
    Random r1 = new Random();
    Random r2 = new Random();
    Scanner sc1 = new Scanner(System.in);
    Scanner sc2 = new Scanner(System.in);
    

    import导包代码书写的位置:在声明包package后,定义所有类class前,使用导包import包名.包名.类名;

第6章 访问修饰符

1)权限修饰符有哪些

  • 在Java中提供了四种访问权限,使用不同的访问权限时,被修饰的内容会有不同的访问权限,以下表来说明不同权限的访问能力:

2)小结

  • 归纳一下:在日常开发过程中,编写的类、方法、成员变量的访问
    • 要想仅能在本类中访问使用private修饰;
    • 要想本包中的类都可以访问不加修饰符即可;
    • 要想本包中的类与其他包中的子类可以访问使用protected修饰
    • 要想所有包中的所有类都可以访问使用public修饰。
    • 注意:如果类用public修饰,则类名必须与文件名相同。一个文件中只能有一个public修饰的类。

第7章 代码块

1)概述:

  • 程序中用大括号括起来的代码叫代码块

2)分类:

  • 局部代码块 构造代码块 静态代码块 同步代码块
7.1 局部代码块

1) 概念:局部代码块是定义在方法或语句中
2) 特点:

  • 以”{}”划定的代码区域,此时只需要关注作用域的不同即可
  • 方法和类都是以代码块的方式划定边界的

3)举例:

     public class Test {

        public static void main(String[] args)  {
            {
                int x = 1;
                System.out.println("普通代码块" + x);
            }
            int a = 99;
            //System.out.println("代码块之外" + x );会报错,找不到x变量
            System.out.println("代码块之外" + a );

            //输出结果为:普通代码块1
            //          代码块之外99
        }
    }

4)作用 :可以限定变量的声明周期.

7.2 构造代码块

1)概念:构造代码块是定义在类中成员位置的代码块
2)特点:

  • 优先于构造方法执行,构造代码块用于执行所有对象均需要的初始化动作
  • 每创建一个对象均会执行一次构造代码块。

3)举例:
定义类:

public class Person {
    private String name;
    private int age;
      public Person(String name,int age) {
          this.name= name;
          this.age = age;
          System.out.println("我是构造方法");
      }
      //构造代码块
      {
          System.out.println("我是构造代码块"); 
      }
}

测试类:

public class Test {
    public static void main(String[] args) {
        new Person("张三",20);
        //输出结果:我是构造代码块
        //        我是构造方法
    }
}
7.3 静态代码块

1)概念:静态代码块是定义在成员位置,使用static修饰的代码块。
2)特点:

  • 它优先于主方法执行、优先于构造代码块执行,当以任意形式第一次使用到该类时执行。
  • 该类不管创建多少对象,静态代码块只执行一次。
  • 可用于给静态变量赋值,用来给类进行初始化。

3)举例:
定义类:

public class Person {
    private String name;
    private int age;
      public Person(String name,int age) {
          this.name= name;
          this.age = age;
          System.out.println("我是构造方法");
      }
      //构造代码块
      {
          System.out.println("我是构造代码块"); 
      }
      static {
          System.out.println("我是静态代码块");
      }
}

测试类:

public class Test {
     public static void main(String[] args) {
            new Person("张三",20);
            new Person("张四",22);
     }
}
//输出结果为:我是静态代码块
//          我是构造代码块
//          我是构造方法
//          我是构造代码块
//          我是构造方法
7.4 同步代码块

(多线程学习)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值