JAVA学习笔记05

关键字Static

如果想让一个成员变量被类的所有实例所共享,就用static修饰即可,称为类变量(或类属性)。

当实例化对象时会给对象属性开辟空间,但有一些属性要求所有对象都一样,就希望不开辟那个属性的空间,直接让属性指向一个公共的空间。这种属性就用static来声明

用来修饰的结构:属性、方法;代码块、内部类;

static修饰属性
对比静态变量与实例变量:

1.个数

静态变量在内存空间中只有一份,被多个对象共享

实例变量类的每个对象一份

2.内存位置

实例对象:在堆空间的对象实体中

3.加载时机

静态变量:随着类的加载而加载

实例变量:随着对象的创建而加载

调用者:

静态变量:可以被类直接调用,也可以使用对象调用

实例变量:只能使用对象进行调用

消亡时机:

静态变量:随着类的卸载而消亡

实例变量:随着对象的消亡而消亡

内存解析

static修饰方法

可以通过"类.静态方法"直接调用静态方法

静态方法内可以调用用静态的属性或静态的方法,不可以调用非静态结构(如:属性,方法)

开发中,什么时候要将属性或方法声明为静态的

方法内操作的变量是静态变量,建议声明为静态方法

开发中,常常将工具类中的方法,声明为静态方法

单例模式

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法

实现思路

要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类的内部仍可以产生该类的对象。因为在类的外部无法创建该类的对象,所以必须要提供一个静态方法来获得这个对象。静态方法只能访问类中的静态成员变量所以,指向类内部产生的该类对象的变量也必须定义成静态的。

如何实现

饿汉式

//饿汉式
class Bank{
    //类构造器私有化
    private Bank(){

    }
    //内部创建类
    private static Bank instance = new Bank();
    //获取当前实例
    public static Bank getInstance(){
        return instance;
    }
}

懒汉式

class GirlFriend{
    private GirlFriend(){
        
    }
    
    static GirlFriend instance = null;
    
    private static GirlFriend getInstance(){
        if(instance == null)
        {
            instance = new GirlFriend();
        }
        return instance;
    }
}
对比两种模式

饿汉式:立即加载,随着类的加载唯一实例就创建了

懒汉式:延迟加载,需要使用的时候实例才创建

优缺点:

饿汉式:(优点)内存中加载早,线程安全(缺点)内存中占用时间长

懒汉式:(优点)节省内存空间(缺点)线程不安全

应用场景

app是单例的典型应用

应用程序的日志应用

理解main方法的语法

public static void main(){}

理解一:可以看作是一个普通的静态方法

理解二:看做是程序的入口格式是固定的

类的成员之四:代码块

代码块的作用:用来初始化类或对象的信息
代码块的修饰:只能使用static进行修饰
    //静态代码块
    {
        System.out.println("非静态代码块");
    }
代码块的分类:

静态代码块:用static进行修饰的

非静态代码块:不用static进行修饰的

具体使用

静态代码块:>随着类的加载而执行  >由于类的加载只会执行一次所以这个静态代码块也只会执行一次  >用来初始化类的信息  >只能调用静态的结构

非静态代码块:>随着对象的创建而执行  >用来初始化对象的信息   >静态非静态结构 都能调用

从类加载开始的执行顺序

静态代码块 --> 普通代码块 --> 构造器

总结:属性赋值过程

1.可以给类的非静态对象赋值的位置有:

>默认初始化  >显式初始化,代码块中初始化 >构造器中初始化      (按顺序的)

>有了对象后通过 对象.属性的方法赋值

final关键字

final 可以用来修饰的结构:类,方法,变量

用法:final修饰类:表示此类不能被继承

final修饰方法:表示此方法不能被重写

final修饰类:不能有子类

final修饰变量:此时的变量其实就变成了常量,一旦赋值就不可更改

final与static搭配:修饰成员变量时,此成员变量称为:全局常量

abstract关键字

被abstract修饰的类不能实例化

被abstract修饰的方法 只有方法的声明没有方法体

包含抽象方法的类,必须是抽象类

继承抽象类的子类必须重写抽象类中的抽象方法

abstract不能与哪些关键字共用?

不能用abstract修饰私有方法,静态方法,final的方法,final的类。

接口

定义接口关键字:interface

接口内部结构的说明:

可以声明:

属性:必须使用public static final修饰

方法:jdk8之前:声明抽象方法,修饰为public abstract

jdk8:声明静态方法,默认方法

public class SubClassTest {
    public static void main(String[] args) {
        //1 接口中声明的静态方法只能通过接口调用,实现类用不了
        CompareA.methodA();
       // SubClass.methodA();//会报错
  
        //2 接口中声明的默认方法可以被实现类继承
        //3 如果类实现了两个接口,而两个接口中有同名同参数的默认方法。则实现类在没有重写此两个接口相同默认方法的情况下会报错
        SubClass s1 = new SubClass();
        s1.method2();
        
        //4 子类在没有重写方法的情况下,在继承类,实现接口的情况下,优先实现父类的方法
    }
}
public class SubClass extends SuperClass implements CompareA,CompareB{
    public void method(){
        CompareA.super.method2();       //调用接口默认方法的写法
    }
}

jdk9:声明私有方法

接口与类的关系:实现关系

格式:class A extend superA implement B,C{}

A相较于superA来讲叫做子类,

A相较于B,C来讲,叫做实现类。

满足此关系后,说明:

类可以实现多个接口,弥补单继承性的局限性

类必须将实现的接口中的所有抽象方法都重写,方可实例化。或者声明为抽象类

接口与接口的关系:继承关系,而且可以多继承

接口的多态性:接口名  变量名 = new 实现类对象;

面试题:区分抽象类和接口

共性:都可以声明抽象方法,都不能实例化

不同:抽象类一定有构造器。接口没有构造器

类与类之间是继承关系,接口与类之间是实现关系,接口与接口之间是多继承关系

内部类

将一个类A定义在类B中,A就是内部类,B就是外部类

分类

>成员内部类:直接声明在外部类的里面。

        >静态类成员

        实例创建:静态成员类      new 外部类.内部类()

         

        >非静态成员类   

        实例创建:  需要先实例化外部类

Person p1 = new Person();
Person.Bird bird = new Bird();

>局部内部类:声明在方法内,构造器内,代码块内部类

成员内部类的理解:

>从类的角度看:

        -内部可以声明属性,方法,构造器,代码块,内部类等结构

        -可以继承父类,可以实现接口

        -可以用final,abstract修饰

>从外部类的成员的角度看:

        -可以调用外部类的结构

        -各种权限修饰词都能用

        -可以使用static修饰

枚举类

枚举类型本质上也是一种类,只不过这个类的对象是有限的,固定的几个,不能让用户随意创建。

本质上就是在类的内部给你造好了不让你自己造

例子:性别:男,女

> 开发中,如果针对某个类,其实例时确定个数的。则推荐将此类声明为枚举类。

> 如果枚举类的实例只有一个,则可以看作是单例的实现方式

使用方法

enum Season1{
    
    //1必须在开头声明实例化对象,对象间用,隔开
    SPRING("春","暖"),
    SUMMER("夏","热");
    //私有变量
    private final String SeasonName;
    private final String SeasonDesc;

    //构造器
    private Season1(String seasonName, String seasonDesc) {
        SeasonName = seasonName;
        SeasonDesc = seasonDesc;
    }

    //提供get方法
    public String getSeasonName() {
        return SeasonName;
    }

    public String getSeasonDesc() {
        return SeasonDesc;
    }
}

使用enum关键字定义的枚举类,默认其父类是java.lang.Enum类,不要再显示的定义其父类,否则报错.

枚举类实现接口的操作

enum Season1 implements Saysth{

    //1必须在开头声明实例化对象,对象间用,隔开
    SPRING("春","暖"){    //让枚举类的每一个对象去重写接口中的抽象方法
        @Override
        public void say() {
            System.out.println("春天啦");
        }
    },
    SUMMER("夏","热"){
        @Override
        public void say() {
            System.out.println("夏天啦");
        }
    };
    //私有变量
    private final String SeasonName;
    private final String SeasonDesc;

    //构造器
    private Season1(String seasonName, String seasonDesc) {
        SeasonName = seasonName;
        SeasonDesc = seasonDesc;
    }

    //提供get方法
    public String getSeasonName() {
        return SeasonName;
    }

    public String getSeasonDesc() {
        return SeasonDesc;
    }
//方式一直接重写接口,不同枚举类对象调用此方法,执行的是同一个方法
//    @Override
//    public void say() {
//        System.out.println("1");
//    }
}

interface Saysth{
    public void say();
}

注解Annotation

包装类

由于有很多只针对对象设计的API,基本数据类型无法穿入,所以有了包装类,目的是把基本数据类型也给传入。

使用方式:

基本数据类型 --> 包装类   

//推荐
int i1 = 1;
Integer ii1 = Integer.valueOf(i1);

//不推荐
int i2 = 1;
Integer ii2 = new Integer(i2)

包装类-->基本数据

Integer ii1 = Integer.valueOf(1)
int i1 = ii1.intValue()

jdk5.0新特性:自动装箱,自动拆箱。

int i1 =1;
Integer ii1 = i1 //自动装箱

int i2 = ii1 //自动拆箱

基本数据类型,包装类 ---> String类型:调用String的重载的静态方法valueOf()

int i1 = 10;
String str1 = String.valueOf(i1);

法2

int i2 = 0;
String str2 = i2+""

String类型 --->转换为基本数据类型,包装类:调用包装类的静态方法:parseXxx()

String i1 = "123";
int i1 = Integer.parseInt(s1);

企业真题

静态属性和静态方法是否可以被继承?是否可以被重写?

答:静态方法不能被重写,不存在多态性

是否可以从一个static方法内部发出对非static方法的调用

答:只能通过对象来对非静态方法的调动

被static修饰的成员(类,方法,成员变量)能否再使用private进行修饰?

完全可以,除了代码块

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值