[

](Java%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%B8%89%EF%BC%89)

1.类变量(静态变量)和类方法(静态方法)static

  1. 类变量是所有类对象共享的,类变量可以通过类名.类变量和对象名.类变量来访问,但通常使用类名.类变量
    类变量是在类加载时就创建了,所以我们没有创建对象实例时,也可以通过类名来访问类变量
  2. 静态方法类似于静态变量,开发自己的工具类时,通常使用静态方法,方便使用。静态方法中不能使用this 和super。只能访问静态变量和静态方法。
  1. package com.static_;
  2. public class TestStatic {
  3. public static void main(String[] args) {
  4. Student curry = new Student("Curry");
  5. curry.count++;
  6. Student tom = new Student("Tom");
  7. tom.count++;
  8. Student car = new Student("Car");
  9. car.count++;
  10. System.out.println(curry.count); //3
  11. System.out.println(tom.count); //3
  12. System.out.println(car.count); //3
  13. System.out.println(Student.count); //3
  14. }
  15. }
  16. class Student{
  17. private String name;
  18. public static int count;
  19. public Student(String name) {
  20. this.name = name;
  21. }
  22. }

2.代码块

2.1普通代码块

  • 代码块属于初始化块,属于类中的成员,类似与方法,将逻辑语句封装在方法体中。
  • 把相同的语句,放在一个代码块里,不管调用哪个构造器,创建对象,都会优先调用代码块内容
  • 代码块调用的顺序优先于构造器
  • 当创建一个子类对象,父类的构造器也被调用,所以父类中的代码块也会被调用。
  1. package com.codeblock_;
  2. public class CodeBlock01 {
  3. public static void main(String[] args) {
  4. Movie movie = new Movie("蜘蛛侠");
  5. //结果:
  6. // 电影屏幕打开
  7. // 广告开始
  8. // 电影屏幕打开
  9. // 播放蜘蛛侠
  10. Movie movie1 = new Movie("唐探3", 20, "陈");
  11. //结果
  12. // 电影屏幕打开
  13. // 广告开始
  14. // 电影屏幕打开
  15. // 播放唐探3
  16. }
  17. }
  18. //把相同的语句,放在一个代码块里,不管调用哪个构造器,创建对象,都会优先调用代码块内容
  19. //代码块调用的顺序优先于构造器
  20. class Movie {
  21. {
  22. System.out.println("电影屏幕打开");
  23. System.out.println("广告开始");
  24. System.out.println("电影屏幕打开");
  25. }
  26. private String name;
  27. private double price;
  28. private String director;
  29. public Movie(String name) {
  30. this.name = name;
  31. System.out.println("播放"+ name);
  32. }
  33. public Movie(String name, double price) {
  34. this.name = name;
  35. this.price = price;
  36. System.out.println("播放"+ name);
  37. }
  38. public Movie(String name, double price, String director) {
  39. this.name = name;
  40. this.price = price;
  41. this.director = director;
  42. System.out.println("播放"+ name);
  43. }
  44. }

2.2静态代码块

  • static代码块也叫静态代码块,作用就是对类初始化,而且随着类的加载而执行,并且只会执行一次,如果是普通代码块,每创建一个对象就执行。
  • 调用类的静态成员,静态代码块会被调用。
  • 调用子类的静态成员,父类的静态代码块也会被调用。
  • 使用类的静态成员,普通代码块不会被调用。
  1. package com.codeblock_;
  2. public class CodeBlock02 {
  3. public static void main(String[] args) {
  4. AA aa = new AA();
  5. /*输出:
  6. BB的静态代码块1被执行
  7. AA的静态代码块1被执行
  8. */
  9. System.out.println(Cat.n1);
  10. /*输出:
  11. Animal的静态代码块1被执行
  12. Cat的静态代码块1被执行
  13. 30
  14. */
  15. }
  16. }
  17. class Animal {
  18. static {
  19. System.out.println("Animal的静态代码块1被执行");
  20. }
  21. }
  22. class Cat extends Animal{
  23. public static int n1 = 30;
  24. static {
  25. System.out.println("Cat的静态代码块1被执行");
  26. }
  27. }
  28. class BB {
  29. static {
  30. System.out.println("BB的静态代码块1被执行");
  31. }
  32. }
  33. class AA extends BB{
  34. static {
  35. System.out.println("AA的静态代码块1被执行");
  36. }
  37. }

-创建一个对象时,调用的顺序为
1.调用静态代码块和静态属性初始化。(优先级一样,按定义的顺序调用)。
2.调用普通代码块和普通属性初始化。(优先级一样,按定义的顺序调用。)
3. 构造器。

  1. package com.codeblock_;
  2. public class CodeBlock03 {
  3. public static void main(String[] args) {
  4. A a = new A();
  5. // 结果:
  6. // getN1被调用
  7. // A 的静态代码块被调用
  8. // A的普通代码块被调用%$
  9. // getN2被调用
  10. }
  11. }
  12. class A{
  13. {
  14. System.out.println("A的普通代码块被调用");
  15. }
  16. private int n2 = getN2();
  17. private static int n1 = getN1();
  18. static {
  19. System.out.println("A 的静态代码块被调用");
  20. }
  21. public static int getN1() {
  22. System.out.println("getN1被调用");
  23. return 100;
  24. }
  25. public int getN2() {
  26. System.out.println("getN2被调用");
  27. return 100;
  28. }
  29. }

2.3 创建一个对象时调用顺序的总结

父类静态代码和静态属性初始化->子类静态代码和静态属性初始化->父类普通代码块和普通属性初始化->父类构造方法->子类的普通代码块和普通属性初始化->子类的构造方法。

3.final关键字

  • 被final修饰的类不能被其他类继承
  • 被final修饰的方法不能被子类重写,可以被继承
  • 被final修饰的属性不能被修改
  • final修饰的属性可以在定义时、代码块、构造器中赋值。
  • 被static修饰的final属性只能在定义和静态代码块中赋值
  • final和static搭配使用,不会导致类加载
  1. package com.codeblock_;
  2. public class CodeBlock04 {
  3. public static void main(String[] args) {
  4. System.out.println(Demo.i); //16
  5. }
  6. }
  7. class Demo {
  8. public static final int i = 16;
  9. static {
  10. System.out.println("demo被加载");
  11. }
  12. }

4.abstract

  • 当类的方法没有实现,只有定义时,用abstract修饰该方法,这个方法是抽象方法,同时要用abstract修饰该类,该类为抽象类。
  1. abstract class Animal{
  2. String name;
  3. int age;
  4. abstract public void cry();
  5. }
  • 抽象类不能被实例化
  • 如果一个类继承了抽象类,必须实现抽象类的所有抽象方法,否则也要定义为抽象类。

5.接口

结构

  1. interface InterfaceName{
  2. //属性
  3. //方法(抽象方法,默认实现方法,静态方法)
  4. void function();
  5. default void function1(){};
  6. static void function2() {};
  7. }
  • 普通类使用接口必须实现接口中的所有方法
  • 接口不能被实例化
  • 抽象类实现接口可以不实现接口中所有方法
  • 一个类可以实现多个接口
  • 接口中的方法默认为public abstract
  • 接口中的属性默认为public static final
  • 接口和接口之间是继承关系

6.内部类

  • 内部类可以直接访问外部类私有属性
  • 分类
    定义在类局部位置上(比如方法内)
    1 局部内部类(有类名)
    2 匿名内部类(没有类名)
    定义在类的成员位置上
    1 成员内部类 (没用static修饰)
    2 静态内部类 (使用static修饰)

6.1 局部内部类

  • 可以直接访问外部类的所有成员,包含私有的
  • 不可以添加访问修饰符,因为他的地位就是一个局部变量,但可以使用final
  • 作用域:仅仅在定义它的方法或代码块中
  • 访问外部类中的成员:直接访问
  • 外部类在方法中,可以创建内部类对象,然后调用内部类成员
  • 外部其他类,不能访问内部类
  • 如果外部类与局本内部类的成员重名,遵循就近原则,如果想访问外部类成员,使用外部类名.this.成员
  1. package com.innerclass;
  2. public class LocalInnerClass {
  3. public static void main(String[] args) {
  4. Outer r = new Outer();
  5. r.m1();
  6. }
  7. }
  8. class Outer{
  9. private int n1 = 100;
  10. private void m2() {
  11. System.out.println("m2被调用");
  12. }
  13. public void m1() {
  14. //不可以添加访问修饰符,因为他的地位就是一个局部变量,但可以使用final
  15. //作用域:仅仅在定义它的方法或代码块中
  16. //外部类在方法中,可以创建内部类对象,然后调用内部类成员
  17. final class Inner{
  18. private int n1 = 800;
  19. public void f1(){
  20. System.out.println("Inner 的 n1 =" + n1);
  21. System.out.println("Outer 的 n1 =" + Outer.this.n1);//可以直接访问外部类的所有成员,包含私有的
  22. m2(); //访问外部类中的成员:直接访问
  23. }
  24. }
  25. new Inner().f1();
  26. }
  27. }

6.2 匿名内部类

  • 相当于继承了类或实现了接口
  1. package com.innerclass;
  2. public class AnonymousInnerClass {
  3. public static void main(String[] args) {
  4. Outer01 outer01 = new Outer01();
  5. outer01.method();
  6. }
  7. }
  8. class Outer01 {
  9. private int n1 = 10;
  10. public void method() {
  11. //基于接口的匿名内部类
  12. //类只使用一次,以后不再使用
  13. //tiger 的编译类型 A
  14. //tiger 的运行类型 匿名内部类
  15. A tiger = new A() {
  16. @Override
  17. public void cry() {
  18. System.out.println("老虎叫。。。。");
  19. }
  20. };
  21. Father father = new Father("jack"){
  22. @Override
  23. public void test() {
  24. System.out.println("匿名内部类的test");
  25. }
  26. };
  27. tiger.cry();
  28. father.test();
  29. }
  30. }
  31. interface A {
  32. public void cry();
  33. }
  34. class Father {
  35. public Father (String name){
  36. }
  37. public void test() {}
  38. }

6.3 成员内部类

  • 可以访问外部类的所有成员
  • 可以添加访问修饰符
  1. package com.innerclass;
  2. public class MemberInnerClass {
  3. public static void main(String[] args) {
  4. Outer02 outer02 = new Outer02();
  5. outer02.t1();
  6. Outer02.Inner02 inner02 = outer02.new Inner02(); //创建内部类对象
  7. inner02.say();
  8. }
  9. }
  10. class Outer02 {
  11. private int n1 = 10;
  12. public String name = "张三";
  13. class Inner02 {
  14. public void say() {
  15. System.out.println("n1 = " + n1 + " name = " + name);
  16. }
  17. }
  18. public void t1() {
  19. Inner02 inner02 = new Inner02();
  20. inner02.say();
  21. }
  22. }

6.4 静态内部类

  • 只能访问外部类的静态成员,不能访问非静态成员。
  • 可以添加访问修饰符
  • 可以直接通过外部类名访问
  1. package com.innerclass;
  2. public class StaticInnerClass {
  3. public static void main(String[] args) {
  4. //两种创建内部类的方法
  5. Outer03.Inner03 inner03 = new Outer03.Inner03();
  6. inner03.say();
  7. Outer03.Inner03 inner031 = Outer03.Inner03.getInstance();
  8. inner031.say();
  9. }
  10. }
  11. class Outer03 {
  12. private int n1 = 10;
  13. private static String name = "jack";
  14. static class Inner03 {
  15. //只能访问外部类的静态成员,不能访问非静态成员。
  16. //可以添加访问修饰符
  17. public void say() {
  18. System.out.println(name);
  19. }
  20. public static Inner03 getInstance() {
  21. return new Inner03();
  22. }
  23. }
  24. }