Java基础学习(三)

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

  1. 类变量是所有类对象共享的,类变量可以通过类名.类变量对象名.类变量来访问,但通常使用类名.类变量
    类变量是在类加载时就创建了,所以我们没有创建对象实例时,也可以通过类名来访问类变量
  2. 静态方法类似于静态变量,开发自己的工具类时,通常使用静态方法,方便使用。静态方法中不能使用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);  //3
        System.out.println(tom.count);   //3
        System.out.println(car.count);   //3
        System.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() {
            @Override
            public void cry() {
                System.out.println("老虎叫。。。。");
            }
        };
       Father father = new Father("jack"){
           @Override
           public 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();
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南北有东西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值