Java - static 关键字,final关键字,继承,抽象类,Object类常用API

6.6、static 关键字

定义:用 static 修饰的属性和方法,表示是静态的属性和方法,可以通过类名直接调用
需求:想不创建对象,而能直接通过类名去调用属性和方法使用,就像:Arrays类一样
作用:直接通过类名去调用属性和方法使用
观察:被 static 修饰的方法名或属性名在代码中是斜着的

  1. 使用 static 修饰属性
    语法:修饰符 static 返回值类型 方法名(形参列表){...}
    调用方式:通过类名直接调用静态属性使用
    注意:静态属性是属于类的,不是属于某个对象的,可以实现数据的共享,因为静态属性只有一份,只加载一次

  2. 使用 static 修饰方法
    语法:修饰符 ststic 返回值类型 方法名(形参列表){...}
    调用方式:静态方法可以直接使用类名直接调用
    注意:1)在静态方法中,不能调用非静态方法;
    2)在非静态方法中,可以调用静态方法;
    3)静态方法中,可以调用静态方法

  3. staitc 修饰代码块
    代码块:通过{...}包裹起来的程序,就是代码块
    静态代码块:通过 static 修饰的代码块
    语法:static {...}
    注意:静态代码块在 JVM 加载类的时候,就先加载了,优于对象创建之前,被创建出来

  4. static 修饰常量
    不能够通过赋值的方式修改的量,叫做常量 - 关键字 final
    static 修饰的常量叫做静态常量
    语法:修饰符 static final 数据类型 变量名 = 值;
    规则:静态常量的名称 一般 大写,如果有多个单词,用下划线分隔,比如 比如:EMAIL_NAME

  5. static 关键字的特点
    1)static 用来修饰属性、方法、代码块
    2)static修饰的属性,方法,代码块,可以直接通过类名调用
    3)静态方法不能在普通方法中调用
    4)静态代码块优先于对象加载
    5)static修饰常量 叫做:静态常量
    6)静态属性是属于类的,不是属于某个对象的,可以实现数据的共享,因为静态属性只有一份,只加载一次。

  6. 案例:

package com.xunfang.user.demo;

public class Static01 {
    //注意:userName 是斜体,用 static 修饰的属性或方法是斜体的
    public static String userName = "张三";

    public static final double PI = 3.1415926; //静态常量

    public static void show(){
        System.out.println("这是一个静态方法");
        // show02(); 错误
        // 不能在静态方法中调用非静态方法
    }

    public void show02(){
        System.out.println("这是一个非静态方法");
        show(); //可以在非静态方法中调用静态方法
    }

    //静态代码块 > 代码块 > 方法代码块
    //静态代码块 、代码块,不需要手动调用
    static {
        System.out.println("静态代码块");
    }
    {
        System.out.println("代码块");
    }
    public void po(){
        System.out.println("方法代码块");
    }
}


class Static01Test{
    public static void main(String[] args) {
        Static01 s1 = new Static01();
        s1.po();
        System.out.println(s1.userName); //并不推荐这样使用
        //用 static 修饰过的方法或属性可直接通过类名. 调用,修改
        Static01.userName = "李四"; //直接通过类名调用 userName 修改
        System.out.println(Static01.userName);

        Static01.show();
        //Static01.show02(); // 错误,不能直接通过类名调用非静态方法
        //需要创建一个对象,然后使用非静态的方法和属性
        s1.show02();
        System.out.println(Static01.PI);
    }
}

6.7、代码块

a)局部代码块
一般定义在方法中
语法:方法(){ {...} }
b)构造代码块
一般定义在类中,当对象加载的时候,会执行一次
语法:...
c)静态代码块
一般定义在类中,用 static 关键字修饰,当类加载的时候,执行唯一的一次。
语法:static{...}

6.8、继承

定义:

儿子,继承父亲,父亲继承爷爷
Java中继承:在Java 中,子类可以继承父类的属性和方法,实现代码的重用性
目的:
1)实现代码的优化设计
2)代码的通用性和可扩展性

如何使用继承?

1)优化了 java 的类的代码,提高了代码的重用性和可扩展性,提高代码的质量
2)让类与类之间产生关系

如何实现继承

继承的关键字:extends
语法:

A类、B类、CA extends B
B extends C
A:子类,派生类
B:父类,基类

Java 是 单继承关系 ,但是可以支持多层继承。可多个类继承一个类,不可一个类继承多个类。

案例:

public class Person {
    public String name;
    public int age;
    public char sex;

    public Person(){
        super(); //没有报错。如果没有继承父类,则默认继承 Object 类
        System.out.println("Person 的无参构造方法");
    }
    public Person(String name, int age, char sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        System.out.println("Peerson 的有参构造方法");
    }

    public void showInfo(){
        System.out.print(name + "," + age + "," + sex);
    }
}

public class Student extends Person{
    public String stuNo;

    public Student(){
        System.out.println("Student 的无参构造方法");
    }
    public Student(String name, int age, char sex,String stuNo) {
        super(name, age, sex);
        /*this.name = name;
        this.age = age;
        this.sex = sex;*/
        this.stuNo = stuNo;
    }

    public void study(){
        System.out.println("作为学生要学习");
    }

    public void showInfo(){
        super.showInfo();
        System.out.println("," + stuNo);
    }
}


class StudentTest{
    public static void main(String[] args) {
        Student student1 = new Student();
        Student student = new Student("张三",20,'男',"电信1班");
        student.showInfo();
        student.study();
    }
}

public class Teacher extends Person{
    public String course;

    public Teacher(String name, int age, char sex,String course) {
        super(name, age, sex);
        this.course = course;
    }

    public void teach(){
        System.out.println("老师要教书");
    }

    public void showInfo(){
        super.showInfo();
        System.out.println(",教" + course);
    }
}


class TestTeacher{
    public static void main(String[] args) {
        Teacher teacher = new Teacher("王老师",28,'男',"语文");
        teacher.showInfo();
        teacher.teach();
    }
}

继承的特点

  1. 为了代码的设计的优化,实现代码的重用性,和可维护性,可扩展性。
  2. 让类和类之间产生了关系
  3. 子类不能直接调用父类private修饰的方法和属性,如果要调用,添加getter/setter方法
  4. java中的继承是单继承,但是可以多重继承

继承的条件是什么?

满足 is ....a 关系的都是继承
如:老师是一个人
苹果是一种水果
狗是一种宠物

继承中构造方法的使用要求

1)在继承的关系中,执行的顺序是:
执行父类的属性 -> 执行父类的方法 -> 执行子类的属性 -> 执行子类的方法
2)在继承的构造方法关系中,执行的顺序是:
执行父类的构造方法 -> 执行子类的构造方法

super() 语句

作用:用来调用父类的构造方法
1)使用 super() 调用父类的构造方法,如果父类提供了有参的构造方法,子类必须使用 super() 来调用父类的构造方法
2)如果父类不提供任何的构造方法,那么子类默认在构造方法的第一行使用 super() 表示调用了父类的无参构造方法
3)如果父类提供了有参构造方法,那么子类不默认调用 super() 方法,除非父类提供了无参构造方法,子类构造方法才能调用super()

super 关键字

super 关键字用来调用父类的属性和方法
this 关键字 用来调用本类的成员变量和方法
super关键字的语法
调用父类的属性:super.父类属性名
调用父类的方法:super.父类方法名()

思考

1)如果子类的构造方法第一行写了this语句调用了本类其他构造方法,那么super调用父类的语句还有吗?
不能,因为,this和super语句都要写在第一行,冲突
2)父类构造方法中是否有隐式的super语句呢?
有,因为如果父类不显示的继承一个类,那么默认继承Object类

重写

定义:子类重写父类的方法,提高了方法的可扩展性
特点:

  1. 重写发生在子类和父类之间
  2. 子类重写父类的方法,方法的返回值类型、方法名、形参列表都必须跟父类一样
  3. 子类如果重写了父类的方法,那么自动调用子类重写的方法
  4. 子类的方法的修饰符范围不能比父类的小

6.9、抽象类

抽象类定义一个规范和规则(定义抽象方法),不具体去实现,让实现类去实现这些抽象的方法,这就是抽象类

抽象类和抽象方法,就是定义了一个规范/规则

1)定义:

抽象类:用abstract修饰的类,是抽象类,抽象类中可以定义抽象方法

使用子类去实现抽象方法

2)语法

//定义抽象类
public abstract 类名{
    //可以定义抽象方法
    public abstract 返回值类型 方法名(参数);
}

3)注意

  1. 如果父类定义了抽象方法,那么子类必须重写该抽象方法
  2. 如果子类也不想去重写抽象方法,那么子类也要定义成抽象类
  3. 抽象类中,也可以不写抽象方法
  4. 抽象类中,也可以定义普通方法
  5. 抽象类不能创建对象!

6.10、final 关键字

final 用来修饰变量

用final 修饰的变量,是一个常量

final 用来修饰方法

在父类中,被final 修饰的方法,子类是无法被重写的

final 用来修饰类

  1. final 修饰的类,不能被继承
  2. final 修饰的类,可以继承其他类

6.11、Object 类常用API

Object是类层次结构的根。 每个类都有Object作为超类。 所有对象(包括数组)都实现了这个类的方法

toString()

ctrl + shift + T : 快速找到类

ctrl + O : 快速找到类中的方法

String toString() 返回对象的字符串表示形式

toString() 方法的底层代码:

public String toString(){
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

equals()

  • 指示一些其他对象是否等于此

Object类中的 equals 方法

public boolean equals(Object obj) {
    return (this == obj);
}

String类中 重写 后的 equals 方法

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

自己编写类时,两个对象的比较用 equals 比较的是地址值。要重写可以才可以比较对象的属性

toString 以及 equals 案例

package com.xunfang.user.demo.fanal11;

import java.util.Objects;

public class SuperFather extends Object{
    public String name;
    public int age;
    public char sex;
    public String address;

    public SuperFather(String name, int age, char sex, String address) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.address = address;
    }

    // toString 原本是 hashCode
    @Override
    public String toString() { //重写 toString,返回值改为对象的属性
        return "SuperFather{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", address='" + address + '\'' +
                '}';
    }

    // equals 原本判断的是是不是同一个对象
    @Override
    public boolean equals(Object o) { //重写后判断对象的(部分或所有)属性是否完全相同
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SuperFather that = (SuperFather) o;
        return age == that.age && sex == that.sex && Objects.equals(name, that.name) && Objects.equals(address, that.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, sex, address);
    }


}

class TestSuperFather{
    public static void main(String[] args) {
        SuperFather grandFather1 = new SuperFather("老黄",23,'男',"江南");
        System.out.println("grandFather = " + grandFather1/*.toString()*/);

        SuperFather grandFather2 = new SuperFather("老黄",23,'男',"江南");
        System.out.println("grandFather2 = " + grandFather2.toString());

        //System.out.println(grandFather1 == grandFather2);
        System.out.println(grandFather1.equals(grandFather2));
        System.out.println("================================");

        String str1 = new String("小黄");
        String str2 = new String("小黄");
        System.out.println(str1 == str2); // false
        System.out.println(str1.equals(str2)); // true
        System.out.println("================================");

        String str3 = "大黄";
        String str4 = "大黄";
        System.out.println(str3 == str4); // true
    }
}

hashCode()

int hashCode() 返回对象的哈希码值 
posted @   Thecong  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示