Java(三)(static,代码块,单例设计模式,继承)

目录

static

有无static修饰的成员变量

有无static修饰的成员方法

static的注意事项

代码块

静态代码块

实例代码块

单例设计模式

饿汉式单例写法

懒汉式单例写法

继承

基本概念

注意事项

权限修饰符

单继承

object

方法重写

子类方法中访问其他成员(成员变量,成员方法)

子类构造器


static

静态,可以修饰成员变量,成员方法

有无static修饰的成员变量

成员变量按照有无static修饰,分为两种:

(1)类变量: 有static修饰,属于类,在计算机里只有一份,会被类全部对象共享(每个对象都会有,只需要设置一次)

(2)实例变量(对象的变量):无static修饰,属于每个对象的(需要对每一个变量进行设置)

Java(三)(static,代码块,单例设计模式,继承)_第1张图片

像上面这个图一样,static修饰的name变量是s1和s2共享的,age变量需要对s1和s2分别设置

推荐用类名访问类变量: 类名.类变量

Java(三)(static,代码块,单例设计模式,继承)_第2张图片

下面是我们访问到类中的变量的流程图: 我们的类创建到方法区中,我们的类变量会被存放到堆内存中,我们new出来的对象也会放到堆内存中,我们栈内存会存放一些指令,当我们要访问age时直接到堆内存中访问修改,想访问name时会跳到方法区找到类,然后通过类访问到类变量

Java(三)(static,代码块,单例设计模式,继承)_第3张图片

访问自己的类变量是可以省略不写类名的Java(三)(static,代码块,单例设计模式,继承)_第4张图片

有无static修饰的成员方法

类方法:静态方法,属于类,可以直接用类名访问,也可以用对对象访问

实例方法: 对象的方法

Java(三)(static,代码块,单例设计模式,继承)_第5张图片

Java(三)(static,代码块,单例设计模式,继承)_第6张图片

啥叫工具类: 工具类中的方法都是类方法, 每一个类方法都是用来完成一个功能,不需要创建对象

static修饰的成员方法一般应用在工具类中,而不是实例方法中

当我们想要调用一个类的方法的时候,仅仅只是调用方法,我们直接将这个方法指定成类方法,到时候我们想要调用这个方法的时候直接,用  类名.成员方法  就行了,就不用创建对象,在调用对象的实例的方法,如果再创建一个对象,对象会占内存,这样会浪费内存

工具类定义的时候有什么要求? 工具类不需要创建对象,建议将工具类的构造器私有化

static的注意事项

1.类方法中可以直接访问类的成员,不可以直接访问实例成员

Java(三)(static,代码块,单例设计模式,继承)_第7张图片

2.实例方法既可以直接访问类成员,也可以直接访问实例成员

Java(三)(static,代码块,单例设计模式,继承)_第8张图片

3.实例方法中可以出现this关键字,类方法不可以出现this关键字的

因为我们调用实例方法的时候,是用对象名.实例方法的,其实是有一个对象,this就是我们这个对象

而我们一般调用类方法的时候,一般是用类名.类方法.没有对象,那我这个this就没有指向的对象了

代码块

静态代码块

格式: static { }

特点: 类加载的时候自动执行,由于类只会加载一次,所以静态代码块也只会执行一次

作用:完成类的初始化,一般可以对类变量进行初始化赋值

Java(三)(static,代码块,单例设计模式,继承)_第9张图片

但是代码块只会执行一次,只是在一开始的时候加载类的时候去执行,我们在下面进行验证

Java(三)(static,代码块,单例设计模式,继承)_第10张图片

实例代码块

格式 : { }

特点: 每次创建对象时,执行实例代码块,并在执行构造器前执行

Java(三)(static,代码块,单例设计模式,继承)_第11张图片

单例设计模式

饿汉式单例写法

调用类方法的时候,对象已经创建了的

public class Student {
    // 1.必须私有类的构造器
    private Student()
    {

    }
    // 2.定义一个类变量记住类的一个对象
    private static Student a = new Student();
    //3.定义一个类方法返回类的对象
    public static Student getObject()
    {
        return a;
    }

Java(三)(static,代码块,单例设计模式,继承)_第12张图片创建唯一的一个对象Java(三)(static,代码块,单例设计模式,继承)_第13张图片

懒汉式单例写法

第一次调用方法就创建这个对象,以后调用的时候都返回这个对象

import org.w3c.dom.ls.LSOutput;

public class Student {


    // 1.把类的构造器私有
    private Student()
    {

    }
    // 2. 定义一个类变量,用于储存这个类的一个对象
    private static Student s1;

    // 3. 定义一个类方法,这个方法要保证第一个调用时
    // 才创建一个对象,后面调用的时候都会返回一个对象
    public  static Student getObject()
    {
        if(s1 == null)
        {
            s1 = new Student();
        }
        return s1;
    }

}
public class test {
    public static void main(String[] args) {
        Student stu1 = Student.getObject();
        Student stu2 = Student.getObject();
        System.out.println(stu1 == stu2);
    }
}

我们发现打印出来的结果是true,说明这个设计模式仅仅创建了一个对象

继承

基本概念

Java中提供了一个关键字extends,这个关键字,可以让一个类和另一个类建立起父子关系Java(三)(static,代码块,单例设计模式,继承)_第14张图片

继承的特点: 子类能继承父类的非私有成员(成员变量,成员方法)

继承后对象的创建: 子类的对象是由子类,父类共同完成的

Java(三)(static,代码块,单例设计模式,继承)_第15张图片

Java(三)(static,代码块,单例设计模式,继承)_第16张图片

我们可以用继承来简化代码,不让代码那么繁琐

假若说我要写两个对象,第一个是老师,老师的数据有名字,具有的技能

第二个是快递员,快递员的数据有名字,送快递的单数

我们要创建两个对象的话一般会按照下面这样来创建

// 快递员对象
public class Courier {
    private String name;
    
    private int number;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}
// 老师对象
public class Teacher {
    private String name;
    private String skill;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

我们会发现:老师和快递员都会有一个相同的成员属性:名字

我们可以整一个父类,父类People对象中有neme方法,让老师对象和快递员对象都继承得到父类的公共属性和方法Java(三)(static,代码块,单例设计模式,继承)_第17张图片

// 快递员的对象
public class Courier extends People {

    private int number;

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}
// 老师对象
public class Teacher extends People{
    private String skill;

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

当我们创建老师对象的时候也会访问到父类中的共有方法,通过共有方法,我们就可以设置老师的姓名

public class test {
    public static void main(String[] args) {
        Teacher t1 = new Teacher();
        t1.setName("李小谦");
        System.out.println(t1.getName());
        t1.setSkill("爱讲物理课");
        System.out.println(t1.getSkill());
    }
}

注意事项

权限修饰符

public private protected 缺省

权限的大小关系: public  > protected > 省略 > private 

下面是他们的访问范围

Java(三)(static,代码块,单例设计模式,继承)_第18张图片

Java(三)(static,代码块,单例设计模式,继承)_第19张图片

Java(三)(static,代码块,单例设计模式,继承)_第20张图片

Java(三)(static,代码块,单例设计模式,继承)_第21张图片

单继承

Java是单继承的,一个类只能继承一个直接父类,Java中的类不支持多继承,但是支持多层继承的

Java(三)(static,代码块,单例设计模式,继承)_第22张图片

但是支持多继承

class A{}
class B extends A{}
class C extends B {}

object

object类是Java中所有的类的祖宗

我们在设计类的时候,会默认指定object类的子类

方法重写

啥是方法重写?

当子类觉得父类中的某个方法不好用,或者满足不了自己的需求时,子类可以重写一个方法名称,参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写

注意:重写后,方法的访问Java会遵循就近原则

我们先来展示一下什么是方法重写

Java(三)(static,代码块,单例设计模式,继承)_第23张图片

当我们创建一个C对象的时候,调用print1和print2实例方法的时候,会打印重写方法里面的内容

Java(三)(static,代码块,单例设计模式,继承)_第24张图片

Java(三)(static,代码块,单例设计模式,继承)_第25张图片

尽量在上面标注一个@Override,表示我们在改写父类中的方法

子类方法中访问其他成员(成员变量,成员方法)

按照就近原则

Java(三)(static,代码块,单例设计模式,继承)_第26张图片

子类构造器

特点: 子类的全部构造器,都会先调用父类的构造器,再执行自己

子类构造器是如何实现调用父类构造器的?

默认情况下,子类全部构造器的第一行代码都是super()(写不写默认都是有的),他会调用父类的无参数构造器,如果父类没有无参数构造器,则我们必须在子类构造器中的第一行手写super(里面带有参数,和父类中有参数构造器中的参数一一对应)

Java(三)(static,代码块,单例设计模式,继承)_第27张图片

我们来看看执行结果

Java(三)(static,代码块,单例设计模式,继承)_第28张图片

Java(三)(static,代码块,单例设计模式,继承)_第29张图片

假如说我将父类构造器改为有参数构造器,变成下面这样

Java(三)(static,代码块,单例设计模式,继承)_第30张图片

那我们也必须在子类中手写一个带参数super(),才能执行子类构造器的代码

Java(三)(static,代码块,单例设计模式,继承)_第31张图片

我们看看问什么这么做呢?

Java(三)(static,代码块,单例设计模式,继承)_第32张图片

你可能感兴趣的:(java,开发语言)