static关键词的使用
1.static 静态的
2.static 可以用来修饰:属性,方法,代码块,内部类
3.使用static修饰属性:
3.使用static修饰属性:静态变量(类变量)
3.1属性,按是否使用static修饰,又分为:静态属性vs非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套 类中的非静态属性。当修改其中一个对象中的非静态属性时,不会 导致其他对象中同样的属性值的修改。
静态变量:我们创建了类的多个对象,多个对象共享同一个静态变 量。当通过某一个对象修改静态变量时,会导致其他对象调用此静 态变量时,是修改过了的。
3.2 static修饰属性的其他说明:
3.2.1静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
3.2.2静态变量的加载要早于对象的创建。
3.2.3由于类只加载一次,所以内存中只存在一次
3.3静态变量的距离system.out.println math.pi
4.使用static修饰方法:
1.随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
- 静态方法 非静态方法
类 yes no
对象 yes yes - 静态方法中,只能调用静态的方法或属性
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
5.static注意点:
在静态方法内不能使用this super关键词
6.开发中使用情况
开发中,如何确定一个属性是否要声明为static的?
属性是可以被多个对象所共享的,不会随着对象的不同而不同的。
开发中,如何确定一个方法是否要声明为static的?
操作静态属性的方法,通常设置为static的
〉工具类中的方法,习惯上声明为static的。比如:Math,Arrays. collections
单例设计模式
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
两种模式:饿汉式(一上来就造好对象,提供方法返回对象)
懒汉式(一开始是null, 用的时候才通过方法new一个对象)
单例模式的优点:
由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
区分饿汉式和懒汉式
饿汉式
坏处:对象加载时间长
好处:饿汉式是线程安全的
懒汉式
好处:延迟对象的创建
坏处:目前的写法不安全---》到多线程修改
public class single {
public static void main(String[] args) {
Bank bank1 = Bank.getInstance();
Bank bank2 =Bank.getInstance();
System.out.println(bank1==bank2);
}
}
//饿汉式
class Bank{
//1.私有化构造器
private Bank(){
}
//2.内部创建类的对象
private static Bank instance =new Bank();
//3.提供公共的静态的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
public class sigle2 {
public static void main(String[] args) {
Order order1 =Order.getInstance();
Order order2 = Order.getInstance();
System.out.println(order1==order2);
}
}
//懒汉式
class Order{
//1.私有化构造器
private Order(){
化
private static Order instance =null;
//4.此对象也为static
//3.声明public static 的方法返回当前类对象
public static Order getInstance(){
if(instance==null){
instance =new Order();
}
return instance;
}
}
代码块
1.代码块的作用:用来初始化类、对象
2.代码块如果有修饰的话,只能使用static
3.分类:静态代码块、非静态代码块
4.静态代码块
内部可以有输出语句
随着类的加载而执行,而且只执行一次
如果定义了多个代码块,按照先后顺序执行
只能调用静态的方法或者属性
作用:初始类的属性
5。非静态代码块
内部可以有输出语句
随着对象的创建而执行
每创建一次就执行一次
如果定义了多个代码块,按照先后顺序执行
方法和属性都可以调用
作用:可以在创建对象屎,对对象的属性等进行初始化
6.如果有很多父类子类代码块
由父及子 静态先行
属性赋值的位置
对属性可以赋值的顺序:
①默认初始化
②显式初始化/ ⑤在代码块中赋值(看位置前后)
③构造器中初始化
识有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
final关键字
final可以修饰的结构:类 方法 变量
1.final修饰一个类
此类不能被其他类继承,没有子类
比如:String类 ,System类,StringBuffer类
2.final修饰一个方法
public final void method(){
}
表示不能被重写了
举例 Object类中的getClass方法
3.final修饰一个变量
修饰属性 表示变量为常量 不能修改
注意修饰属性的话不能使用默认值,要使用显式初始化、代码块初始化、构造器初始化
修饰局部变量 该局部变量不能再修改了
static final
修饰属性:全局变量
抽象类
abstract关键字
abstract可以修饰方法和类
1.abstract修饰类:抽象类
此类不能实例化
抽象类中一定有构造器,便于子类对象实例化调用
开发中,都会提供抽象类的子类,让子类实例化,完成相关操作
2.abstract修饰方法:抽象方法
抽象方法只有方法的声明
包含抽象方法的类 一定是抽象类
如果子类继承的父类有抽象类方法,则要重写或者子类也是抽象类
3.abstract注意点
不能修饰属性构造器(构造器不能重写)
不能用来修饰私有方法,静态方法(private方法不能重写),final的方法,final的类
//Employee 是抽象类
//这是声明这个数组是这个类型,没有new 对象 所以没有报错
Employee [] arr =new Employee[2];
匿名子类的对象
//Persons 是抽象类
Person p =new Person(){
@Override
public void eat(){
System.out.println();
}
}
//匿名子类的匿名对象
method1(new Person(){
@Override
public void eat(){
System.out.println()}
})
模板方法设计模式
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
方法的算法固定,里面不同的情况可抽象,子类继承对他进行重写
接口
接口的使用
interface name {
int value =1; //省略了public static final
void eat(); //省略了public abstract
}
1.接口使用interface定义
2.java中,接口和类是并列的两个结构
3.如何定义接口
3.1 JDK7及以前:只能定义全局常量和抽象方法
全局常量: public static final的(书写时可以省略)
抽象方法:public abstract的
3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
4.接口不能定义构造器!所以不能实例化
5.Java开发中,接口通过类去实现(implement)的方式来使用
实现类来实现接口的全部方法,则实现类可以实例化
如果没有全部覆盖接口的方法,则类为抽象类,不能实例化
6.Java类可以实现多个接口
弥补了Java单继承的局限性
class AA extends BB implements cc,dd
7.接口和接口之间可以继承,而且可以多继承
interface AA{
}
interface BB{
}
interface CC extends AA,BB{
}
8.接口的具体使用,体现多态性
9.接口,实际上可以看做一种规范
开发中,体会面向接口编程
10.接口的应用
代理模式,工厂模式(具体看文件)
11.Java8接口新特性
interface AA{
public static void method1(){
System.out.println(); //只能用接口.方法来调用
}
public default void method2(){
System.out.println(); //通过实现类.方法来调用
//实现类可以重写默认方法
//如果实现类继承的父类声明了重名的方法,调用的是父类的方法
//如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错。-->接口冲突。
这就需要我们必须在实现类中重写此方法
}
}
Ball类中的play 把两个接口的play都重写了
ball 是全局变量 不能修改
编译不通过,x不明确。 如果输出 B的x 则要 super.x。要输出A的话 要A.x
如果不重名可以直接写 因为是全局变量
内部类
1.Java中允许将一个类A声明在另一个类B中,则A类是内部类,B是外部类
2.内部类的分类:成员内部类 vs 局部内部类 (方法内、代码块内、构造器内)
3.成员内部类
3.1 作为一个类
类内可以定义属性 方法 构造器等
可以final修饰,表示此类不能被继承
3.2作为成员
可以调用外部类的结构 Name.this.xxx
可以被static修饰
4.关注三个问题
4.1如何实例化内部类
//静态内部类
Person.Dog dog =new Person.Dog();
//非静态内部类 要实例化对象才可以调用
Person p =new Person();
Person.bird bird =p.new Bird();
4.2如何在成员内部类中区分调用外部类的结构
//属性重名的时候 不重名直接用就行
Person.this.name //外部类的属性
this.name //内部类的属性
name //方法的形参
4.3开发中内部类的使用
在局部内部类的方法中(比如: show)如果调用局部内部类所声明的方法(比如:method )中的局部变量要求此局部变量声明为final的。
jdk 7及之前版本:要求此局部变量显式的声明为final的
jdk8及之后的版本。可以省略final的声明