Java - static 关键字,final关键字,继承,抽象类,Object类常用API
6.6、static 关键字
定义:用 static 修饰的属性和方法,表示是静态的属性和方法,可以通过类名直接调用
需求:想不创建对象,而能直接通过类名去调用属性和方法使用,就像:Arrays类一样
作用:直接通过类名去调用属性和方法使用
观察:被 static 修饰的方法名或属性名在代码中是斜着的
-
使用 static 修饰属性
语法:修饰符 static 返回值类型 方法名(形参列表){...}
调用方式:通过类名直接调用静态属性使用
注意:静态属性是属于类的,不是属于某个对象的,可以实现数据的共享,因为静态属性只有一份,只加载一次 -
使用 static 修饰方法
语法:修饰符 ststic 返回值类型 方法名(形参列表){...}
调用方式:静态方法可以直接使用类名直接调用
注意:1)在静态方法中,不能调用非静态方法;
2)在非静态方法中,可以调用静态方法;
3)静态方法中,可以调用静态方法 -
staitc 修饰代码块
代码块:通过{...}包裹起来的程序,就是代码块
静态代码块:通过 static 修饰的代码块
语法:static {...}
注意:静态代码块在 JVM 加载类的时候,就先加载了,优于对象创建之前,被创建出来 -
static 修饰常量
不能够通过赋值的方式修改的量,叫做常量 - 关键字 final
static 修饰的常量叫做静态常量
语法:修饰符 static final 数据类型 变量名 = 值;
规则:静态常量的名称 一般 大写,如果有多个单词,用下划线分隔,比如 比如:EMAIL_NAME -
static 关键字的特点
1)static 用来修饰属性、方法、代码块
2)static修饰的属性,方法,代码块,可以直接通过类名调用
3)静态方法不能在普通方法中调用
4)静态代码块优先于对象加载
5)static修饰常量 叫做:静态常量
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类、C类
A 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();
}
}
继承的特点
- 为了代码的设计的优化,实现代码的重用性,和可维护性,可扩展性。
- 让类和类之间产生了关系
- 子类不能直接调用父类private修饰的方法和属性,如果要调用,添加getter/setter方法
- 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类
重写
定义:子类重写父类的方法,提高了方法的可扩展性
特点:
- 重写发生在子类和父类之间
- 子类重写父类的方法,方法的返回值类型、方法名、形参列表都必须跟父类一样
- 子类如果重写了父类的方法,那么自动调用子类重写的方法
- 子类的方法的修饰符范围不能比父类的小
6.9、抽象类
抽象类定义一个规范和规则(定义抽象方法),不具体去实现,让实现类去实现这些抽象的方法,这就是抽象类
抽象类和抽象方法,就是定义了一个规范/规则
1)定义:
抽象类:用abstract
修饰的类,是抽象类,抽象类中可以定义抽象方法
使用子类去实现抽象方法
2)语法
//定义抽象类
public abstract 类名{
//可以定义抽象方法
public abstract 返回值类型 方法名(参数);
}
3)注意
- 如果父类定义了抽象方法,那么子类必须重写该抽象方法
- 如果子类也不想去重写抽象方法,那么子类也要定义成抽象类
- 抽象类中,也可以不写抽象方法
- 抽象类中,也可以定义普通方法
- 抽象类不能创建对象!
6.10、final 关键字
final 用来修饰变量
用final 修饰的变量,是一个常量
final 用来修饰方法
在父类中,被final 修饰的方法,子类是无法被重写的
final 用来修饰类
- final 修饰的类,不能被继承
- 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() 返回对象的哈希码值
本文来自博客园,作者:Thecong,转载请注明原文链接:https://www.cnblogs.com/hwphwc/p/16492339.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!