Java教程

JAVA基础(四)

本文主要是介绍JAVA基础(四),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

JAVA基础(四)

类变量和类方法

​ 类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的同样也是一个变量。

定义语法:

访问修饰符 static 数据类型 变量名(通常使用)

static 访问修饰符 数据类型 变量名

1、什么时候需要变量类型

当我们需要让某个类的所有对象共享一个变量时,就可以考虑使用类变量(静态变量)

2、类变量与实例变量(普通变量)区别

类变量是该类的所有对象共享的,而实例变量是每个对象共享的。

3、加static称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量

4、类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,但java设计者推荐使用 类名.类变量名方式访问。(前提是满足访问修饰符的访问权限和范围)

5、实例变量不能通过 类名.类变量名 方式访问

6、类变量是在类加载时就初始化了,即使没有创建对象,只要类加载了,就可以使用类变量了

7、类变量的生命周期是便随加载开始,随着类消亡而销毁。

类方法使用:

1、类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区:

类方法中无this的参数 普通方法中隐含着this的参数

2、类方法可以通过类名调用,也可以通过对象名调用

3、普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用。

4、类方法中不能使用和对象相关的关键字,比如this 和super。普通方法(成员方法)可以。

5、类方法(静态方法)中 只能访问静态变量 或者静态方法

6、普通成员方法,既可以访问普通变量(方法)

小结: 静态方法,只能访问静态成员,非静态的方法,可访问静态成员和非静态成员(必须遵守访问权限)

深入理解main方法

解释main方法的形式: public static void main (String[] args){}

1、main方法时虚拟机调用

2、java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public

3、java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static

4、该方法接收String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数

特别提示:

1、在main()方法中,可以直接调用main方法所在类的静态方法或静态属性。

2、但是,不能直接访问该类中的非静态成员,必须创建该类的一个实例对象,才能通过这个对象去访问类中的非静态成员。

代码块:

代码化块又称初始化块,属于类中的成员(即类的一部分),类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。

但和方法不同,没有方法名,没有返回,没有参数 ,只要方法体,而且不通过对象或类显式调用,而是加载类时,或者创建对象时隐式调用。

基本语法 [修饰符]{代码块}

注:

1、修饰符 可选,要是写的话,也只能写static

2、代码块分为两类,使用static修饰的叫静态代码块,没有static修饰 叫普通代码块。

3、逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)

4、;分号可以写上,也可以省略。

代码块的使用:

1、static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次,如果是普通代码块,每创建一个对象,就执行。

2、类什么时候被加载 【重点】

创建对象实例时(new)

创建子类对象实例,父类也会被加载

使用类的静态成员时(静态属性、静态方法)

3、普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会被调用一次。如果只是使用类的静态成员时,普通代码并不会执行。

小结:1、static代码块是类加载时,执行,只会执行一次

​ 2、普通代码就是在刚创建对象时调用的,创建一次,调用一次

​ 3、类加载的3种情况。【重点】

4、创建一个对象时,在一个类调用顺序

​ 1、调用静态代码块和静态属性初始化(注:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)

​ 2、调用普通代码和普通属性的初始化(注:普通代码块和普通属性初始化调用的级别一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)

​ 3、调用构造方法。

5、构造器的最前面其实隐含了super()和调用普通代码块,新写一个类演示静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优先于 构造器普通代码块的。

6、创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,够造方法的调用顺序:

  1. 父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
  2. 子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
  3. 父类的普通代码和普通属性初始化(优先级一样,按定义顺序执行)
  4. 父类构造方法
  5. 子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
  6. 子类的构造方法

7、静态代码块只能调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

什么是设计模式?

1、静态方法和属性的经典使用。

2、设计模式是在大量实践中总结和理论之后优选的代码结构、编码风格、以及解决问题的思考方式。

什么是单例设计模式?(单个的实例)

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

2、单例设计模式有两种方式:1、饿汉式 2、懒汉式

步骤:

  1. 构造器私有化,防止直接New
  2. 类的内部创建对象(该对象是static)
  3. 向外暴漏一个静态的公共方法。getInstance

饿汉式VS懒汉式

  1. 二者最主要的区别在于创建对象的时机不同;饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建。
  2. 饿汉式不存在线程安全问题,懒汉式存在线程安全问题。
  3. 饿汉式存在浪费资源的可能。因为如果一个对象实例都没有使用,那么饿汉式创建对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。
  4. javaSE标准类中,java.lang.Runtime就是经典的单例模式。

饿汉式(缺点 在类加载时就创建,可能存在资源浪费)

class GirlFriend {
    private String name;
    //为了能够在静态方法中返回gf对象,需要将其修饰为static
    //饿汉式可能创建了对象 但是没有用
  private static GirlFriend gf = new GirlFriend("小混混");
    //如何保证只能创建一个对象
    //步骤【单例模式-饿汉式】
    //1.将构造器私有化
    //2.在类的内部直接创建(该对象是static)
    //3.提供一个公共的static方法,返回gf对象
    private GirlFriend(String name) {
        this.name = name;
    }
    public static GirlFriend getInstance(){
        return gf;
    }

}

懒汉式(缺点:线程安全问题)

 //希望在程序运行时,只能创建一个Cat对象
    class Cat{
    private static Cat cat;
    private String name;
    //步骤
     //1.构造器私有化
     //2.创建一个static静态属性
     //3.提供一个public的static方法,可以返回一个Cat对象
     //4、懒汉式 只有当用户使用getInstance时,才返回cat对象,后面再次调用时,
    // 会返回上次创建的cat对象,从而保证单例
     private Cat(String name){
        this.name=name;
    }
    public static Cat getInstance(){
         if(cat == null){
             cat = new Cat("小可爱");
         }
        return cat;
    }
}

final关键字

final可以修饰类、属性、方法和局部变量

使用Final的某些情况:

1、当不希望被类继承时,可以使用final修饰

2、当不希望父类的某个方法被子类覆盖/重写时,可以使用final关键字修饰。

3、当不希望类的某个属性的值被修改,可以用final修饰。

4、当不希望某个局部变量被修改,可以使用final修饰。

final注意事项:

  1. final修饰的属性又叫常量。
  2. final修饰的属性在定义,必须赋初始值并且以后不能再修改,赋值可以在定义时、在构造器中、在代码块中
  3. 如果final修饰的属性是静态的,则初始化的位置只能是 在定义上时,在静态迪代码块,不能在构造器中赋值。
  4. final类不能继承 ,但可以实例化对象。
  5. 如果类不是final类,但是含有final方法虽然不能重写,但是可以被继承。

5、如果一个类已经是final类了,就没有必要再将方法修饰成final方法。

6、final不能修饰构造方法(即构造器)

7、final和static往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理。

8、包装类(Integer、Double、Float、Boolean等都是final),String也是final类

抽象类:

1、用abstract 关键字来修饰一类时,这个类就叫抽象类,访问修饰符 abstract类名{}。所谓抽象方法就是没有实现的方法,所谓没有实现的方法就是指没有方法体。

2、用abstrct 关键字来修饰一个方法时,这个方法就抽象方法,访问修饰符 abstract 返回类型 方法名(参数列表);

3、抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类。

抽象类使用注意:

1、抽象类不能被实例化。(简单说)

2、抽象类不一定要包含abstract方法。抽象类可以,没有abstract方法。

3、一旦类包含了abstract 方法,则这个类必须声明为abstract。

4、abstract 只能修饰类和方法,不能修饰属性和其他的。

当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类。

5、如果一个类继承了抽象类,则它必须实现抽象方法,除非他自己也声明为abstrace类

6、抽象方法不能使用private、final 和 static 来修饰 ,因为这些关键字都是和重写相违背的。

接口:

接口就是给出一些 没有实现的方法,封装到一起,把某些类要使用的时候,在根据具体情况把这些方法写出来。语法:

interface 接口名{

//属性和方法(1.抽象方法2.默认实现方法3.静态方法)

}

class 类名 implement 接口{

自己属性和方法

必须实现的接口的抽象方法

}

1、接口不能实例化(不能new)

2、接口中所有的方法是public方法,接口中抽象方法,可以不用abstract修饰

3、一个普通类实现接口,就必须将该接口所有方法都实现 可以使用Alt +Enter来解决。

4、抽象类去实现接口时,可以不实现接口的抽象方法

5、一个类可以实现多个接口

6、接口中的属性,只能是final的,而且public static final修饰符。

7、接口中的属性的访问形式:接口名.属性名

8、一个接口不能继承其它的类,但是可以继承多个别的接口

9、接口的修饰符 只能是public和默认,这点和类的修饰符是一样的。

小结:1、在jdk7.0 前 接口里的所有方法都没有方法体。2、jdk8.0后接口类可以有所有静态方法,默认方法,也就说说接口中可以有方法的具体实现。

实现接口 VS 继承类

当子类继承了父类,就自动的拥有父类的功能,如果子类需要扩展功能,就可以通过实现接口的方式扩展。

继承的价值主要在于:解决代码的复用性和可维护性。

接口的价值主要在于:设计,设计好各种规范(方法),让其它类去实现这些方法

接口在一定程度上实现代码解耦。[即:接口规范性+动态绑定]

内部类:

一个类的内部又完成的嵌套一个类结构。被嵌套的类称为内部类,嵌套其他类的类称为外部类。

类的五大成员:属性、方法、构造器、代码块、内部类

内部类分类:

定义在外部局部位置上:1、局部内部类(有类名) 2、匿名内部类(没有类名)

定义在外部类的成员位置上:1、成员内部类(没有static修饰) 2、静态内部类 (使用static修饰)

局部内部类的使用

1、可以直接访问外部类的所有成员,包含私有的。

2、不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的,但是可以使用final修饰。因为局部变量也可以使用final

3、作用域:仅仅在定义它的方法或代码块中

4、局部内部类–>访问–>外部类的成员(访问方式:直接访问)

5、外部类–>访问–>局部内部类成员 访问方式:创建对象,再访问(注:必须在作用域内)

6、外部其他类–>不能访问–>局部内部类

7、如果外部类和内部类重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类.this.成员)去访问

匿名内部类:

1、基本语法:本质是类 内部类 该类没有名字 同时还是一个对象

new 类或接口(参数列表){

类体

};

2·、匿名内部类的语法比较奇特,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征。

3、可以直接访问外部类的所有成员,包含私有的。

4、不能添加访问修饰符,因为它的地位就是一个局部变量。

5、作用域:仅仅在定义它的方法或代码块中。

6、匿名内部类–>访问–>外部类成员[直接访问]

7、外部其他类—不能访问—>匿名内部类(因为匿名内部类地位是一个局部变量)

8、如果外部类和匿名内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类成员,则可以使用(外部类.this.成员)去访问。

成员内部类:成员内部类是定义在外部类的成员位置,并且没有static修饰

1、可以直接访问外部类的所有成员,包含私有的

2、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。

3、作用域:和外部类的其他成员一样,为整个类体。

4、成员内部类—>访问—>外部类(eg:属性)(访问方式:直接访问)

5、外部类—>访问—>内部类 访问方式:创建对象,再访问

6、外部其他类–>访问–>成员内部类

7、如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类.this.成员)去访问。

静态内部类:静态内部类是定义在外部类的成员位置,并且static修饰

1、可以直接访问外部类的所有静态成员,包含私有的 但不能直接访问非静态成员。

2、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。

3、作用域:同其他的成员,为整个类体。

4、静态内部类—访问—>外部类(比如:静态属性)[访问方式:直接访问所有静态成员]

5、外部类—访问—>静态内部类 访问方式:创建对象,再访问

6、外部其他类–访问—>静态内部类

这篇关于JAVA基础(四)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!