[
](Java%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%B8%89%EF%BC%89)
1.类变量(静态变量)和类方法(静态方法)static
- 类变量是所有类对象共享的,类变量可以通过类名.类变量和对象名.类变量来访问,但通常使用类名.类变量
类变量是在类加载时就创建了,所以我们没有创建对象实例时,也可以通过类名来访问类变量 - 静态方法类似于静态变量,开发自己的工具类时,通常使用静态方法,方便使用。静态方法中不能使用this 和super。只能访问静态变量和静态方法。
package com.static_;public class TestStatic {public static void main(String[] args) {Student curry = new Student("Curry");curry.count++;Student tom = new Student("Tom");tom.count++;Student car = new Student("Car");car.count++;System.out.println(curry.count); //3System.out.println(tom.count); //3System.out.println(car.count); //3System.out.println(Student.count); //3}}class Student{private String name;public static int count;public Student(String name) {this.name = name;}}
2.代码块
2.1普通代码块
- 代码块属于初始化块,属于类中的成员,类似与方法,将逻辑语句封装在方法体中。
- 把相同的语句,放在一个代码块里,不管调用哪个构造器,创建对象,都会优先调用代码块内容
- 代码块调用的顺序优先于构造器
- 当创建一个子类对象,父类的构造器也被调用,所以父类中的代码块也会被调用。
package com.codeblock_;public class CodeBlock01 {public static void main(String[] args) {Movie movie = new Movie("蜘蛛侠");//结果:// 电影屏幕打开// 广告开始// 电影屏幕打开// 播放蜘蛛侠Movie movie1 = new Movie("唐探3", 20, "陈");//结果// 电影屏幕打开// 广告开始// 电影屏幕打开// 播放唐探3}}//把相同的语句,放在一个代码块里,不管调用哪个构造器,创建对象,都会优先调用代码块内容//代码块调用的顺序优先于构造器class Movie {{System.out.println("电影屏幕打开");System.out.println("广告开始");System.out.println("电影屏幕打开");}private String name;private double price;private String director;public Movie(String name) {this.name = name;System.out.println("播放"+ name);}public Movie(String name, double price) {this.name = name;this.price = price;System.out.println("播放"+ name);}public Movie(String name, double price, String director) {this.name = name;this.price = price;this.director = director;System.out.println("播放"+ name);}}
2.2静态代码块
- static代码块也叫静态代码块,作用就是对类初始化,而且随着类的加载而执行,并且只会执行一次,如果是普通代码块,每创建一个对象就执行。
- 调用类的静态成员,静态代码块会被调用。
- 调用子类的静态成员,父类的静态代码块也会被调用。
- 使用类的静态成员,普通代码块不会被调用。
package com.codeblock_;public class CodeBlock02 {public static void main(String[] args) {AA aa = new AA();/*输出:BB的静态代码块1被执行AA的静态代码块1被执行*/System.out.println(Cat.n1);/*输出:Animal的静态代码块1被执行Cat的静态代码块1被执行30*/}}class Animal {static {System.out.println("Animal的静态代码块1被执行");}}class Cat extends Animal{public static int n1 = 30;static {System.out.println("Cat的静态代码块1被执行");}}class BB {static {System.out.println("BB的静态代码块1被执行");}}class AA extends BB{static {System.out.println("AA的静态代码块1被执行");}}
-创建一个对象时,调用的顺序为
1.调用静态代码块和静态属性初始化。(优先级一样,按定义的顺序调用)。
2.调用普通代码块和普通属性初始化。(优先级一样,按定义的顺序调用。)
3. 构造器。
package com.codeblock_;public class CodeBlock03 {public static void main(String[] args) {A a = new A();// 结果:// getN1被调用// A 的静态代码块被调用// A的普通代码块被调用%$// getN2被调用}}class A{{System.out.println("A的普通代码块被调用");}private int n2 = getN2();private static int n1 = getN1();static {System.out.println("A 的静态代码块被调用");}public static int getN1() {System.out.println("getN1被调用");return 100;}public int getN2() {System.out.println("getN2被调用");return 100;}}
2.3 创建一个对象时调用顺序的总结
父类静态代码和静态属性初始化->子类静态代码和静态属性初始化->父类普通代码块和普通属性初始化->父类构造方法->子类的普通代码块和普通属性初始化->子类的构造方法。
3.final关键字
- 被final修饰的类不能被其他类继承
- 被final修饰的方法不能被子类重写,可以被继承
- 被final修饰的属性不能被修改
- final修饰的属性可以在定义时、代码块、构造器中赋值。
- 被static修饰的final属性只能在定义和静态代码块中赋值
- final和static搭配使用,不会导致类加载
package com.codeblock_;public class CodeBlock04 {public static void main(String[] args) {System.out.println(Demo.i); //16}}class Demo {public static final int i = 16;static {System.out.println("demo被加载");}}
4.abstract
- 当类的方法没有实现,只有定义时,用abstract修饰该方法,这个方法是抽象方法,同时要用abstract修饰该类,该类为抽象类。
abstract class Animal{String name;int age;abstract public void cry();}
- 抽象类不能被实例化
- 如果一个类继承了抽象类,必须实现抽象类的所有抽象方法,否则也要定义为抽象类。
5.接口
结构
interface InterfaceName{//属性//方法(抽象方法,默认实现方法,静态方法)void function();default void function1(){};static void function2() {};}
- 普通类使用接口必须实现接口中的所有方法
- 接口不能被实例化
- 抽象类实现接口可以不实现接口中所有方法
- 一个类可以实现多个接口
- 接口中的方法默认为public abstract
- 接口中的属性默认为public static final
- 接口和接口之间是继承关系
6.内部类
- 内部类可以直接访问外部类私有属性
- 分类
定义在类局部位置上(比如方法内)
1 局部内部类(有类名)
2 匿名内部类(没有类名)
定义在类的成员位置上
1 成员内部类 (没用static修饰)
2 静态内部类 (使用static修饰)
6.1 局部内部类
- 可以直接访问外部类的所有成员,包含私有的
- 不可以添加访问修饰符,因为他的地位就是一个局部变量,但可以使用final
- 作用域:仅仅在定义它的方法或代码块中
- 访问外部类中的成员:直接访问
- 外部类在方法中,可以创建内部类对象,然后调用内部类成员
- 外部其他类,不能访问内部类
- 如果外部类与局本内部类的成员重名,遵循就近原则,如果想访问外部类成员,使用外部类名.this.成员
package com.innerclass;public class LocalInnerClass {public static void main(String[] args) {Outer r = new Outer();r.m1();}}class Outer{private int n1 = 100;private void m2() {System.out.println("m2被调用");}public void m1() {//不可以添加访问修饰符,因为他的地位就是一个局部变量,但可以使用final//作用域:仅仅在定义它的方法或代码块中//外部类在方法中,可以创建内部类对象,然后调用内部类成员final class Inner{private int n1 = 800;public void f1(){System.out.println("Inner 的 n1 =" + n1);System.out.println("Outer 的 n1 =" + Outer.this.n1);//可以直接访问外部类的所有成员,包含私有的m2(); //访问外部类中的成员:直接访问}}new Inner().f1();}}
6.2 匿名内部类
- 相当于继承了类或实现了接口
package com.innerclass;public class AnonymousInnerClass {public static void main(String[] args) {Outer01 outer01 = new Outer01();outer01.method();}}class Outer01 {private int n1 = 10;public void method() {//基于接口的匿名内部类//类只使用一次,以后不再使用//tiger 的编译类型 A//tiger 的运行类型 匿名内部类A tiger = new A() {@Overridepublic void cry() {System.out.println("老虎叫。。。。");}};Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类的test");}};tiger.cry();father.test();}}interface A {public void cry();}class Father {public Father (String name){}public void test() {}}
6.3 成员内部类
- 可以访问外部类的所有成员
- 可以添加访问修饰符
package com.innerclass;public class MemberInnerClass {public static void main(String[] args) {Outer02 outer02 = new Outer02();outer02.t1();Outer02.Inner02 inner02 = outer02.new Inner02(); //创建内部类对象inner02.say();}}class Outer02 {private int n1 = 10;public String name = "张三";class Inner02 {public void say() {System.out.println("n1 = " + n1 + " name = " + name);}}public void t1() {Inner02 inner02 = new Inner02();inner02.say();}}
6.4 静态内部类
- 只能访问外部类的静态成员,不能访问非静态成员。
- 可以添加访问修饰符
- 可以直接通过外部类名访问
package com.innerclass;public class StaticInnerClass {public static void main(String[] args) {//两种创建内部类的方法Outer03.Inner03 inner03 = new Outer03.Inner03();inner03.say();Outer03.Inner03 inner031 = Outer03.Inner03.getInstance();inner031.say();}}class Outer03 {private int n1 = 10;private static String name = "jack";static class Inner03 {//只能访问外部类的静态成员,不能访问非静态成员。//可以添加访问修饰符public void say() {System.out.println(name);}public static Inner03 getInstance() {return new Inner03();}}}
