static、抽象

1.静态成员和实例成员

static 静态的
可以修饰方法,内部类,代码块,属性.
静态代码块:

static{
    System.out.println("静态代码块");
}

静态代码块无需调用,在类装载时就会执行.作用是为静态变量赋初始值,很少用.

static修饰的称为静态成员,非static修饰的称为实例成员.
静态成员和实例成员的区别?
1.访问方式不同:
静态成员通过类名访问 EmpFac.createEmp();(类名.方法名)
实例成员通过对象来访问,先new出对象. 对象.方法名();
2.内存加载机制不同:
静态成员在程序运行时,就被加载到内存的静态区域中.
实例成员在执行到new时,把对应的内容加载到内存的堆区域中.
3.生命周期不同:
静态成员在程序退出运行时,从内存中被销毁.
实例成员要根据Java的垃圾回收机制来决定何时销毁.

所有对象使用的是同一静态变量.
普通成员变量:
普通成员变量
静态成员变量:
静态成员变量

  • A:代码块概述

    • 在Java中,使用{}括起来的代码被称为代码块。
  • B:代码块分类

    • 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
  • C:常见代码块的应用

    • a:局部代码块

      • 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
    • b:构造代码块 (初始化块)

      • 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
    • c:静态代码块

      • 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。

      • 一般用于加载驱动

        2.静态成员和实例成员的访问区别

        private static String str1;
        private String str2;

      private static void test1() {
      //在静态方法中访问非静态变量
      // Cannot make a static reference to the non-static field str2
      str2 = “11”;
      //静态方法访问静态变量,没问题
      str1 = “22”;
      }
      静态方法可以直接访问静态成员,不可以直接访问实例成员.必须先new对象,通过对象来访问.
      实例方法既可以直接访问实例成员,也可以直接访问静态成员.

3.单例设计模式

在程序运行过程中,某个类的对象只允许被创建一次
例如:播放器的播放窗口,单点登录
在Java中让类的对象在程序运行中只执行一次:
使用单例设计模式,实现过程:
1)构造方法私有
2)声明一个静态的 当前类类型的属性.
3)声明一个静态方法,返回值为当前类类型.在方法体内判断第2步的静态属性是否为空,如果为空,new一个对象并赋值给静态属性,返回这个静态属性

public class Play {
    private Play() {
        //构造方法私有
    }
    //声明一个当前类类型的静态属性
    private static Play play;
    //声明一个返回值为当前类类型的静态方法
    public static Play getInstance() {
        if (play == null) {
            play = new Play();
        }
        return play;
    }
}

public class Test01 {
    public static void main(String[] args) {
        Play s1 = Play.getInstance();
        Play s2 = Play.getInstance();
        System.out.println(s1);//xxxxxx.Play@5b464ce8
        System.out.println(s2);//xxxxxx.Play@5b464ce8  ↑内存地址相同,同一个对象
    }
}

分析:
根据new的时机不同,又分为懒汉模式和饿汉模式;
懒汉模式:在程序运行后,并没有立即去判断play是否为null,决定是否创建对象;而是在调用静态方法后再去判断play是否为null,以及是否创建对象
饿汉模式:在程序运行后立即创建对象,通过静态方法来获取对象.
饿汉模式:
1)构造方法私有
2)声明一个当前类类型的静态属性=new 类名();
3)声明一个返回值为当前类类型的静态方法,返回第二步的静态属性;

public class Play2 {
    private Play2() {
    //构造方法私有
    }
    //声明一个当前类类型的静态属性
    private static Play2 play = new Play2();
    //声明一个返回值为当前类类型的静态方法
    public static Play2 getInstance() {
        return play;
    }
}

Play2 p1 = Play2.getInstance();
Play2 p2 = Play2.getInstance();
System.out.println(p1);//xxxxx.Play2@6d06d69c
System.out.println(p2);//xxxxx.Play2@6d06d69c 内存地址相同,同一个对象

如果使用单例对象比较频繁,并且在程序运行后立刻使用单例对象,建议使用饿汉模式;
如果使用单例对象频率较低,为了节省内存空间,建议使用懒汉模式.

4.抽象方法,抽象类

抽象方法:用abstract修饰的,没有方法体及{}的方法.
(没有方法体没有abstract修饰,但是有{}的叫虚方法)

public abstract void bark();

说明:1.抽象方法所在的类一定是抽象类.
2.子类继承父类后,一定要实现(重写)父类中所有的抽象方法,除非子类也是抽象的.
//–话说难道不是因为子类拥有父类所有的属性及方法,包括抽象方法,但是抽象方法又必须在抽象类中,所以才会报错,需要给重写成一个普通的方法么
3.抽象方法约束了其子类必须实现(重写)父类中的抽象方法,起了规范约束的作用.
//如果有不希望被声称对象的类也可以用抽象类

抽象类:使用abstract修饰的类

public abstract class Animal{
}

特点:
1.抽象类不能被实例化
2.抽象类有构造方法.子类可以在构造方法中通过super调用父类的构造方法进行属性的初始化.
3.抽象类中可以有抽象方法,也可以有非抽象方法

5. 接口

继承:描述的是类之间的 is-a关系
子类 is-a 父类
学生 人类
继承的特点:基类单继承,传递性

接口interface
特点:
1.接口中的方法必须是公共的,抽象的方法.但是public
和abstract可以省略;
2.接口中的属性默认是变量,都是public static
final,但是public和static可以省略;
3.接口不能被实例化;
4.接口没有构造方法;
5.接口是对Java中基类单继承的拓展(只能继承一个父类,但是可以实现多个接口)

说明:类在实现接口后,一定要实现接口中的所有方法,除非类是抽象的.

接口可以继承接口,多继承

public interface Interface3 extends Interface1,Interface2{//可以继承多个接口
    public void test3();
} 

实现是一种特殊的继承;子类可以多继承接口.需要在子类中重写接口的全部方法.

public interface USB {
    void say();
    public static final int age = 1;//public & static 可以省略,必须final常量
}
public class  implements USB,Interface3{
    public void say(){
        System.out.println("aaa");
    }
    public void test3(){
        System.out.println("bbb");
    }
}

子类对象也可以向上转型成父类接口的类型

UsbPhone bb = new UsbPhone();
USB cc = (USB)bb;

接口分离原则:接口中的方法分类越详细越好
面试题:接口和抽象类的区别?什么时候使用抽象类,什么时候使用接口?
1).抽象类中既可以有抽象方法,也可以有非抽象方法
接口中的方法必须是公共的,抽象的;
2).抽象类中的属性是普通属性
接口中的变量必须具有public static final,必须赋值.
3).抽象类有构造方法,而接口没有构造方法
4).继承(实现):抽象类是类,只能单继承;接口可以多继承
选择依据:
1)is-a还是has-a的关系
2)单继承还是多实现