abstract、static、final

抽象类

概念

被abstract修饰的类称为抽象类。抽象类意为不够完整的类、不够具体的类,抽象类对象无法独立存在,即不能new对象。

特点

  • 抽象类和抽象⽅法必须⽤abstract 关键字修饰
    • abstract class 类名{}
    • abstract 返回追类型 ⽅法名();
  • 抽象类不⼀定有抽象⽅法, 有抽象⽅法的类⼀定是抽象类或者接⼝
  • 抽象类不能实例化, 必须由⼦类继承并重写抽象⽅法来实例化
  • 抽象类的⼦类
    • 抽象类
    • 重写抽象类中的所有抽象⽅法(普通类)

语法

abstract class 类名{}

语法示例:

public abstract class Employee {
    public void sign(){
        System.out.println("指纹打卡");
    }
    public abstract void work();
    }
}
public class Hr extends Employee{
    @Override
    public void work() {
    	System.out.println("招聘⼈才");
    }
}
public class Coder extends Employee{
    @Override
    public void work() {
    	System.out.println("努⼒的敲代码");
    }
}

示例:

public class abstractClass {
    public static void main(String[] args) {
        //抽象类无法实例化,所以使用多态指向子类
        Animal dog = new Dog();
        dog.eat();
        Animal cat = new Cat();
        cat.eat();
    }
}

//抽象类
abstract class Animal {
    String bread;
    String sex;
    int age;

    //抽象方法
    public abstract void eat();

}

//子类继承父类
class Dog extends Animal {
    //    重写父类eat方法
    @Override
    public void eat() {
        System.out.println("狗子在啃骨头");
    }

}

//子类继承父类
class Cat extends Animal {
    //    重写父类eat方法
    @Override
    public void eat() {
        System.out.println("猫咪在吃鱼");
    }
}

抽象方法

定义

被abstract修改的方法,称为抽象方法,只有方法声明,没有方法实现的部分({})

意为不完整的方法,必须包含在抽象类中。

注意事项

产⽣继承关系之后,子类必须重写⽗类中的所有的抽象⽅法,否则⼦类还是抽象类

格式

权限修饰符 abstract 返回类型 方法名();
public abstract void eat();

public class Vehicle {
    public static void main(String[] args) {
        Master master = new Master();
        master.setName("jack");
        Ve ve = new Car("宝马");
        master.goHome(ve);
        Ve ve1 = new Bike("凤凰");
        master.goHome(ve1);
    }
}

class Master {
    private String name;

    public void goHome(Ve ve) {
        System.out.println(this.name + "回家了");
        ve.run();
    }

    public Master() {
    }

    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

abstract class Ve {
    private String brand;

    public abstract void run();

    public Ve() {
    }

    public Ve(String brand) {
        this.brand = brand;
    }

    public String getBrand() {

        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

}

class Car extends Ve {
    public Car() {
    }

    public Car(String brand) {
        super(brand);
    }

    @Override
    public void run() {
        System.out.println(super.getBrand() + "交通工具正在前进!");
    }
}

class Bike extends Ve {
    public Bike() {
    }

    public Bike(String brand) {
        super(brand);
    }

    @Override
    public void run() {
        System.out.println(super.getBrand() + "交通工具正在前进!");
    }
}

总结

abstract修饰类:不能new对象,但可以声明引用。
abstract修饰方法:只有方法声明,没有方法实现。(需包含在抽象类中)
抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类。
子类继承抽象类后,必须重写父类中所有的抽象方法,否则子类还是抽象类。

static

定义

  • ⽤于修饰类的成员, 表示静态
  • ⼀旦被修饰, 类的成员将不再属于这个类创建的对象

特点

  • 随着类的加载而加载
  • 优先于对象存在
  • 被类的所有对象共享
  • 通过类名调用
    • 本身可以使用对象名调用
    • 推荐使用类名调用
  • 优先于非静态成员
  • 类的所以静态成员都存储于静态方法区中

静态属性

静态属性不是属于哪一个变量,而是属于整个类

格式:static 数据类型 属性名;
static int count;

在调用静态属性时使用    类名.属性名

示例:

class TestStudent {
    public static void main(String[] args) {
        
        Student student = new Student();
        student.name = "jack";
        System.out.println("第一个同学名字叫:" + student.name);
        Student.count = 50;
        System.out.println("该班共有" + Student.count + "个学生");
    }
}

public class Student {
    //实例属性:属于某个学生
    String name;
    //静态属性:属于整个班级,也就是学生类
    static int count;
}
public class Teacher {
    String name;
    int age;
    double salary;
    static int count = 0;

    public void show() {
        System.out.println(name + "---" + age + "---" + salary);
    }

    //实例化Teacher默认调用Teacher的无参构造方法,所以在这里 Teacher.count++;计算
    public Teacher() {
        Teacher.count++;
    }
}

class testTeacher {
    public static void main(String[] args) {
        System.out.println("创建对象之前次数" + Teacher.count);
        Teacher teacher1 = new Teacher();
        teacher1.name = "jack";
        teacher1.age = 26;
        teacher1.salary = 9854;
        Teacher teacher2 = new Teacher();
        teacher2.name = "zhuli";
        teacher2.age = 28;
        teacher2.salary = 9556.25;
        Teacher teacher3 = new Teacher();
        teacher3.name = "mike";
        teacher3.age = 65;
        teacher3.salary = 36523.8;
        teacher1.show();
        teacher2.show();
        teacher3.show();
        System.out.println("创建对象之后次数" + Teacher.count);
    }
}

初始化顺序

静态成员变量 ==> 静态代码块 ==> 成员变量 ==> 构造代码块 ==> 构造⽅法

静态成员变量和静态代码块(构造代码块)谁写在前⾯谁先执⾏

局部、成员、类变量的区别

  1. 类中位置不同
    局部变量位于方法内
    成员变量和类变量在类中方法的外面
  2. 内存的位置不同
    局部变量位于栈内存中
    成员变量位于堆内存中
    类变量位于静态方法区
  3. 初始值不同
    局部变量手动初始化
    成员变量和类变量对应数据类型的初始值
  4. 生命周期不同
    局部变量随着方法的调用出现,随着方法的结束消亡
    成员变量随着对象的创建出现,随着对象的消失消亡
    类变量随着类的加我而出现,jvm关闭而消亡
  5. 修饰不同
    局部变量和成员变量没有static修筋
    类变量使用static修饼
  6. 份数不同
    成员变量,在堆内存中可以同时存在多个
    类变量,在内存中仅有一个
  7. 归属不同
    局部变量属于方法本身,每个方法独享
    成员变量,属于对象本身,每个对象独享
    类变量,属于类本身,类的所有实例对象共享

静态方法

定义

  • 通过对静态的了解, 我们得知, 存放于⽅法区之中,属于类,我们也称之为类成员
  • 当⼀个类的成员被频繁使⽤的时候, 就可以写成静态的,以便于提⾼效率
  • 当⼀个属性或⽅法被所有的对象共享的时候

格式

在方法中添加static该方法就变成了静态方法

修饰符 static 返回类型 方法名(){}
public static void method() {}

调用静态方法时使用    类名.方法名    Teacher.method();

public class Teacher {
    public static void method1() {
        System.out.println("method1");
    }

    public static void method2() {
        //相同类直接方法名即可
        method1();
    }
}

class testTeacher {
    public static void main(String[] args) {
        Teacher.method2();
    }
}

特点

  • ​ 静态方法允许直接访问静态成员。
  • ​ 静态方法不能直接访问非静态成员。
  • ​ 静态方法中不允许使用this或是super关键字。
  • ​ 静态方法可以继承,不能重写、没有多态。

静态代码块

概念

类加载时,触发静态代码块的执行(仅一次)。
执行地位:静态属性初始化之后。

作用

可为静态属性赋值,或必要的初始行为。

格式

static{//代码体}

    static {
        System.out.println("method1");
    }
public class Person {
    String name;
    //静态属性:人口最大量
    static int max;

    //静态代码块,类加载的时候触发,并且只执行一次
    static {
        max = 1000;
        System.out.println("人口最大量:" + max);
    }

    public static void method() {

    }
}

class TestPerson {
    public static void main(String[] args) {
//        无论实例化几次或者调用静态方法几次,静态代码块只触发一次
//        Person person=new Person();
//        Person person1=new Person();
//        Person person2=new Person();
        Person.method();
    }
}

注意事项

  1. JVM首次使用某个类时,需通过CLASSPATH查找该类的.class文件。静态随着类的存在⽽存在, 随着类的消亡⽽消亡, jvm不关闭, 静态就⼀直存在, 太多话 ,容易造成内存溢出
  2. 将.class文件中对类的描述信息加载到内存中,进行保存。
    ·如:包名、类名、父类、属性、方法、构造方法…
  3. 加载时机:
    • ​ 创建对象
    • ​ 创建子类对象
    • ​ 访问静态属性
    • ​ 调用静态方法
    • ​ 主动加载:Class.forName(“全限定名”);
  4. 静态的成员在内存中只有⼀份,所有的操作指向的都是同⼀个静态成员
  5. 静态可以极⼤的提升运⾏的效率
  6. 频繁被使⽤的成员要写成静态的

总结

  • static修饰的成员为静态成员,无需创建对象,可直接通过类名访问。
  • 静态方法不能直接访问非静态成员。
  • 静态方法中不能使用this或super。
  • 静态方法可以继承、不能重写、没有多态。
  • 静态代码块在类加载时被执行,且只执行一次。

静态和非静态

  1. this关键字的问题
    • 静态⽅法中⽆法使⽤this关键字, 因为静态⽅法调⽤的时候, 不需要对象
    • ⾮静态⽅法中可以使⽤this关键字, 因为⾮静态⽅法在调⽤的时候必须有对象
  2. 访问成员变量
    • 静态⽅法只能访问静态的成员变量, 如果要使⽤⾮静态的成员变量,必须先创建对象
    • ⾮静态的⽅法可以直接访问静态的成员变量,也可以直接访问⾮静态的成员变量
  3. 访问成员方法
    • 静态⽅法只能访问静态⽅法,如果想使⽤⾮静态⽅法就必须要创建对象
    • ⾮静态⽅法可以直接访问静态⽅法,也可以直接访问⾮静态⽅法
  4. 静态只能访问静态(直接调⽤)
public class Demo {
    static String name = "李四";
    int age = 18;
    public static void method1(){
        //静态⽅法可以直接访问静态成员⽅法
        System.out.println(name);
        //这⾥会报错
        //System.out.println(age);
        //静态要访问⾮静态的成员变量必须要创建对象
        Demo demo = new Demo();
        System.out.println(demo.age);
        //静态⽅法可以直接访问静态⽅法
        method3();
        //静态⽅法想要访问⾮静态⽅法必须要先创建对象
        demo.method4();
    }
    public void method2(){
        //⾮静态可以直接访问静态成员变量
        System.out.println(name);
        //⾮静态⽅法可以直接访问⾮静态的成员变量
        System.out.println(age);
        //⾮静态⽅法可以直接访问静态成员⽅法
        method3();
        //⾮静态⽅法可以直接直接⽅法⾮静态⽅法
        method4();
    }
    //静态⽅法
    public static void method3(){
    }
    //⾮静态⽅法
    public void method4(){
    }
}

最终类、方法、常量

概念

最后的,不可更改的。

特点

  1. 修饰类:类不能被继承
  2. 修饰变量:变量变成常量,只能被赋值一次(初始化赋值)
  3. 修饰方法:方法不能被重写

修饰局部变量

  1. 基本数据类型:值不能被改变
  2. 引用数据类型:地址值不能被改变,对象中的属性可以改变
  3. final可以修饰形参

修饰成员变量的初始化时机

  • 必须手动赋值
  • 对象初始化完毕之前
  • 类初始化完成前(静态)
public class Demo {
    final String name = "⼩红";
    {
        //name = "⼩红";
    }
    public Demo(){
        //name = "⼩红";
    }
}

final类

final修饰类:此类不能被继承。
String、Math、System均为final修饰的类,不能被继承。

public final class Person {
    String name;
}

Person类无法被继承,因为final

final方法

该方法不能被覆盖

class Person {
    public final void run() {

    }
}

class Pe extends Person {
    //此处无法编译,提示错误:'run()' cannot override 'run()' in 'util.Person'; overridden method is final
    @Override
    public void run() {
        super.run();
    }
}

当重写final修饰的方法时,系统会提示错误:‘run()’ cannot override ‘run()’ in ‘util.Person’; overridden method is final

final变量

格式:
    final 数据类型 变量名=值;    

final int num=10;
final修饰变量:此变量值不能被改变(常量)。

总结

  • final修饰类:此类不能被继承。
  • final修饰方法:此方法不能被覆盖。
  • final修饰变量:此变量值不能被改变。(无初始值、只允许赋值一次)
    • ​ 局部常量:显示初始化。
    • ​ 实例常量:显示初始化、构造方法。
    • ​ 静态常量:显示初始化、静态代码块。
    • ​ 基本类型常量:值不可变。
    • ​ 引用类型常量:地址不可变。

java值传递

  1. 基本数据类型的传递

    • 基本数据类型传递是值, 也就是将具体的值赋给变量名,所以变量名代表的是具体的值
  2. 引用数据类型传递的是地址值

    • 当⼀个对象赋值给⼀个对象名, 是将这个对象在内存中的地址值传递给对象名
    • 实例对象在对内存中是有⼀个16进制的地址值
  3. String的传递

    • String ⽐较特殊, 她虽然是⼀个引⽤变量, 但是她传递的是具体的数值
    • String ⾸先是在对内存中创建⼀个对象,对象⾥⾯封装的是常量值, 然后将数值放⼊到常量池中,再指向String
  4. 总结

    基本数据类型传递的是值, 引⽤数据类型传递的是址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值