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)单继承还是多实现