08 stack关键字和继承

582 阅读6分钟

01 static关键字

  • static关键字修饰成员变量表示静态的含义,此时成员变量由对象层级提高为类层级,也就是说整个类只有一份并且被所有对象所共享,该成员变量随着类的加载准备就绪,与是否创建对象无关。
  • static关键字修饰的成员可以使用引用.的方式来访问,但推荐使用类名.的方式。

static关键字的使用方式:

  • 在非静态成员方法中既能访问非静态成员也能访问静态成员(成员:成员变量+成员方法,静态成员被所有对象共享)
  • 在静态成员方法中只能访问静态成员不能访问非静态成员(成员:成员变量+成员方法,因为此时可能还未创建对象)
  • 在开发中只有隶属于类层级并被所有对象所共享的内容才可以使用static关键字修饰(不能滥用static关键字)

02 构造块和静态代码块

构造块:在类体中直接使用{}括起来的代码块

public class Person{
  {
    代码块;
  }

}

每创建一次对象都会执行一次构造块

静态代码块:使用static关键字修饰的构造块

public class Person{
  static {
    代码块;
  }

}

静态代码块随着类加载时执行一次

03 单例设计模式

在某些特殊的场合,一个类只对外提供且只提供一个对象时,这样的类叫单例类,而设计单例的流程和思想叫做单例设计模式。

单例设计模式的实现流程:

  1. 私有化构造方法,使用private关键字修饰构造方法
  2. 声明本类类型的引用指向本类型的对象,并使用private static关键字共同修饰
  3. 提供公有的get方法负责将对象返回出去,并使用public static关键字共同修饰

具体实现代码:

//饿汉式实现单例模式
public class Singleton {
    private static Singleton sin=new Singleton();
    private Singleton(){}
    private static Singleton getInstance(){
        return sin;
    }
    
}
//懒汉时实现单例模式
public class Singleton {
    private static Singleton sin=null;
    private Singleton(){}
    private static Singleton getInstance(){
      if(sin==null){
        sin=new Singleton();
      }
    
        return sin;
    }
    
}

单例模式的实现方式有两种:分别是饿汉式和懒汉式,一般比较推荐饿汉式

04 继承

当多个类之间有相同的特征和行为时,可以将相同的行为和特征提取出来组成一个公共类,让多个类吸收公共类中已有的特征和行为而在多个类中只需要编写自己独有的特征和行为的机制,称为继承。

在Java语言中使用extends关键字来表示继承关系,比如Student类继承Person类

public class Student extends Person{

}

使用继承的好处是提供代码的复用性,可维护性以及可扩展性,并且是多态的前提条件

继承的特点:

  • 子类不能继承父类的构造方法和私有方法,但私有成员变量可以继承,只是不能直接访问
  • 无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类继承过来的成员变量,相当于在构造方法的第一行增加代码super()的效果
  • 使用继承必须满足逻辑关系:子类 is a 父类,也就是不滥用继承
  • Java语言只支持单继承,并不支持多继承,也就是说一个字类只能有一个父类,而一个父类可以有多个子类

05 方法重写

从父类继承下来的方法不满足子类的需求时,就需要在子类中重新写一个和父类一样的方法来覆盖从父类继承下来的版本,这种方式称为方法重写(Override)

方法重写的原则:

  • 要求方法名相同、参数列表相同以及返回值类型相同,从Java5开始允许返回子类类型
  • 要求方法的访问权限不能变小,可以相同或者变大
  • 要求方法不能抛出更大的异常(异常机制)

06 构造块和静态代码块常见笔试考点

下面代码的执行循序是如何?

public class SpuerTest {
    {
        System.out.println("SuperTest类中的构造块");//a
    }
    static {
        System.out.println("SuperTest类中的静态代码块");//b
    }
    public SpuerTest(){
        System.out.println("SuperTest类中的构造方法体");//c
    }
}

public class SubSuperTest {
    {
        System.out.println("SubSuperTest类中的构造块");//d
    }
    static {
        System.out.println("SubSuperTest类中的静态代码块");//e
    }
    public SubSuperTest(){
        System.out.println("SubSuperTest类中的构造方法体");//f
    }

    public static void main(String[] args) {
        SubSuperTest ss=new SubSuperTest();
    }
}

代码的执行顺序是:beacdf

由上面的结果可见:

  • 先执行父类的静态代码块,在执行子类的静态代码块
  • 执行父类的构造块,再执行父类的构造方法体
  • 执行子类的构造块,再执行子类的构造方法体

07 访问控制

常用的访问控制符

2.PNG

总结就是:

  • public修饰的成员可以在任意的位置使用
  • private修饰的成员只能在本类内部使用
  • 通常情况下,成员方法都使用public关键字修饰,成员变量都使用private关键字修饰

08 package语句

定义类时需要指定类的名称,但如果仅仅将类名作为类的唯一标识符,则不可避免的出现命名冲突的问题,这回给组件复用以及团队间的合作带来麻烦,而在Java语言中就使用包(package)来解决命名冲突的问题。

包的定义:在定义一个类时,除了定义类的名称一般还要指定一个包名,格式如下:package 包名 或者 package 包名1.包名2...包名n

这样做的好处是实现项目管理、解决命名冲突以及权限控制的效果

需要注意的一点是包的命名也是有规范的,比如org.apache.commons.lang.StringUtil,其中StirngUtil是类名而org.apache.commons.lang是多层包名,org.apache表示公司或者组织的信息(域名信息的反写);commons是项目名称;lang是模块的名称。

包的导入:

  • 使用import关键字导入包
  • 使用import关键字导入静态成员(Java5开始支持)

09 final关键字

final本意为“不可改变、最终的”,修饰类、成员方法和成员变量

final使用方式:

  • final修饰类,则该类无法被其他类所继承(主要用于防止滥用继承)
  • final修饰成员方法,则该方法不能被重写但可以继承(防止不经意间的改写)
  • final修饰成员变量,则该变量必须初始化且不能改变(防止不经意间造成改变)

在实际开发中很少单独使用final关键字来修饰成员变量,通常使用public static final关键字共同修饰成员变量来表达常量的含义,常量的命名规范要求所有的字母都要大写,不同单词之间采用下划线连接。

public static final double PI=3.14;