Java——面向对象进阶(一)

在这里插入图片描述

前言
面向对象进阶(一):static,继承,this和super关键字


文章目录

  • 一、static
    • 1.1 静态变量
    • 1.2 静态方法
    • 1.3 静态变量和静态方法在内存中
  • 二、继承
    • 2.1 概念
    • 2.2 继承的特点和能继承什么
    • 2.3 继承中的重写
    • 2.4 this和super关键字

一、static

在 Java 中,static 关键字用于声明类中的静态成员(包括字段、方法、内部类和代码块)。静态成员属于类本身,而不是类的实例。

1.1 静态变量

静态变量(也称为类变量)是在类中使用 static关键字声明的变量。

特性

  1. 类级别共享:静态变量属于类本身,而不是类的实例。所有实例共享同一个静态变量。意味着静态变量不依赖于实例而存在。
  2. 单一存储:在内存中只有一份静态变量,无论创建了多少个类的实例。
  3. 生命周期:静态变量在类加载时初始化,并在程序结束时销毁。
  4. 访问方式:可以通过类名直接访问,也可以通过实例访问(但不推荐)。

用法

声明静态变量

静态变量在类体中用 static 关键字声明。通常在类的顶部声明。

public class MyClass {public static int staticVar = 0;
}

访问静态变量

静态变量可以通过类名直接访问,也可以通过实例访问。

public class Main {public static void main(String[] args) {// 通过类名访问静态变量MyClass.staticVar = 5;System.out.println(MyClass.staticVar); // 输出: 5// 通过实例访问静态变量(不推荐)MyClass obj1 = new MyClass();MyClass obj2 = new MyClass();obj1.staticVar = 10;System.out.println(obj2.staticVar); // 输出: 10,因为obj1和obj2共享同一个静态变量}
}

示例:计数器

静态变量的一个常见用法是作为计数器,记录创建的实例数量。

public class Counter {public static int count = 0;public Counter() {count++;}public static void displayCount() {System.out.println("Number of instances: " + count);}
}public class Main {public static void main(String[] args) {Counter obj1 = new Counter();Counter obj2 = new Counter();Counter obj3 = new Counter();Counter.displayCount(); // 输出: Number of instances: 3}
}

在这个例子中,每次创建 Counter 类的实例时,静态变量 count 都会增加1。由于 count 是静态变量,它在所有实例中共享,因此可以准确记录创建的实例数量。


1.2 静态方法

静态方法(Static Methods)是用 static 关键字修饰的方法,属于类本身,而不是类的实例。它们在类加载时就被初始化,可以不通过实例对象而直接调用。静态方法在很多情况下都非常有用,特别是在工具类中。

特性

  1. 类级别方法:静态方法属于类,可以直接通过类名调用,而不需要创建类的实例。
  2. 不能访问实例成员:静态方法不能直接访问类的实例变量和实例方法,因为它们不属于任何具体的实例。
  3. 可以访问静态成员:静态方法可以访问类的静态变量和其他静态方法。
  4. 无需对象:静态方法在调用时不需要创建对象,可以通过类名直接调用。

用法

声明静态方法

静态方法在类体中使用 static 关键字声明。

public class MyClass {public static void staticMethod() {System.out.println("This is a static method.");}
}

访问静态方法

静态方法可以通过类名直接调用,也可以通过实例调用(但不推荐)。

public class Main {public static void main(String[] args) {// 通过类名调用静态方法MyClass.staticMethod();// 通过实例调用静态方法(不推荐)MyClass obj = new MyClass();obj.staticMethod();}
}

示例:实用工具类

静态方法非常适合用来实现实用工具类中的一些方法。例如,数学运算方法、字符串处理方法等。

工具类(Utility Class)是在编程中常用的一种类,专门用于封装一组静态方法,这些方法通常是与特定任务相关的通用功能。工具类的主要特点是它们不需要实例化,可以直接通过类名调用其方法。常见的工具类包括用于字符串处理、数学运算、日期时间操作等功能的类。

public class MathUtils {public static int add(int a, int b) {return a + b;}public static int multiply(int a, int b) {return a * b;}
}public class Main {public static void main(String[] args) {int sum = MathUtils.add(5, 3);int product = MathUtils.multiply(4, 2);System.out.println("Sum: " + sum);        // 输出: Sum: 8System.out.println("Product: " + product); // 输出: Product: 8}
}

静态方法不能直接访问实例变量和实例方法,举例:

public class Example {// 实例变量private int instanceVar = 42;// 实例方法public void instanceMethod() {System.out.println("Instance method called. Instance variable: " + instanceVar);}// 静态方法public static void staticMethod() {// 试图访问实例变量 - 这会导致编译错误// System.out.println("Instance variable: " + instanceVar);// 试图调用实例方法 - 这会导致编译错误// instanceMethod();// 正确的访问方式:静态方法只能访问静态变量和静态方法System.out.println("Static method called.");}// 静态变量public static int staticVar = 84;// 另一个静态方法public static void anotherStaticMethod() {System.out.println("Another static method called. Static variable: " + staticVar);}
}public class Main {public static void main(String[] args) {// 调用静态方法Example.staticMethod();// 创建类的实例Example example = new Example();// 调用实例方法example.instanceMethod();// 调用另一个静态方法Example.anotherStaticMethod();}
}

解释:在 staticMethod 中,尝试直接访问 instanceVarinstanceMethod 会导致编译错误,因为 instanceVarinstanceMethod 都是属于实例的,而不是类的。静态方法没有 this 引用,因此无法引用实例成员。


1.3 静态变量和静态方法在内存中

静态变量和静态方法都存储在方法区(Method Area)中

方法区是 JVM 内存的一部分,用于存储类结构信息(如类元数据、常量池)和静态变量。

内存简易图

在这里插入图片描述


二、继承

2.1 概念

继承(Inheritance)是面向对象编程中的重要概念之一,继承是一种类之间的关系,其中一个类(称为子类或派生类)根据规则可以继承另一个类(称为父类或基类)的属性和方法。继承可以避免重复编写相同的代码,更好地组织和管理类之间的关系。

例如,我们要实现学生类和老师类,学生和老师之间必然存在共性,比如都有名字,年龄等成员变量,以及可能有吃饭,睡觉等成员方法,那么就极有可能存在代码重复实现的情况。那我们就可以定义一个父类,比如person类,在类中有名字,年龄成员变量,以及一些成员方法,然后学生类和老师类再继承person类。

在这里插入图片描述

2.2 继承的特点和能继承什么

特点

  1. Java只支持单继承,不支持多继承,但支持多层继承
  2. 多层继承:子类A继承父类B,子类B继承父类C…
  3. 另外,所有其他类都直接或间接地继承自 Object类,因为Object 类是所有类的根类,Object 类定义了几个核心方法,包括 toString(), equals(), hashCode()

能够继承什么?
在这里插入图片描述

我们来挨个解释:
对于构造方法:无论构造方法是否是私有的,它都不能被继承,这是为了保证对象在创建过程中的合理初始化,以及遵循面向对象编程中的封装和可见性原则。

对于成员变量:

  • 子类继承父类时,会继承父类的成员变量。
  • 子类可以继承父类的 publicprotected 访问权限的成员变量。如果成员变量被声明为 private,则子类无法直接访问该成员变量,需要借助继承自父类的 get/set 方法。
  • 如果子类定义了与父类同名的成员变量,那么父类的成员变量会被子类的成员变量隐藏。这种情况下,可以使用 super 关键字访问父类被隐藏的成员变量。(super 关键字在 Java 中用于调用父类的构造方法和访问被隐藏的父类成员变量或方法。)

子类定义了与父类同名的成员变量,用 super 关键字

class Parent {public int number = 10;public void display() {System.out.println("Parent's number: " + number);}
}class Child extends Parent {public int number = 20;public void display() {super.display(); // 调用父类的 display 方法System.out.println("Child's number: " + number);System.out.println("Parent's number: " + super.number); // 访问父类的成员变量}
}

对于成员方法:

  • 子类可以继承父类的非私有成员方法。private 方法不可继承,因为它们对子类不可见。
  • 子类可以提供自己的实现来覆盖从父类继承的同名方法(重写)。
  • final 修饰的方法不能被子类重写,因此不能继承。
  • static 方法属于类级别的方法,不属于实例,不能被继承。

2.3 继承中的重写

方法的重写(Override)是子类覆盖父类中具有相同名称和参数的方法。

重写的规则

  1. 必须是被子类继承的父类成员方法,才能是重写

  2. 方法签名:子类重写父类方法时,方法名、参数列表必须与父类方法完全相同。

  3. 访问修饰符:子类重写父类方法时,访问修饰符不能更严格。例如,如果父类方法是 protected,子类重写时可以使用 protected 或者 public,但不能使用 private 或者默认的(package-private)修饰符。

  4. 返回类型:重写方法的返回类型必须与被重写方法的返回类型相同,或者是其子类。

  5. @Override 注解可以帮助编译器验证是否成功重写了父类方法。

示例

下面是一个展示方法重写的示例:

// 父类
class Parent {// 父类方法public void display() {System.out.println("Parent's display method");}
}// 子类继承自父类
class Child extends Parent {// 重写父类的 display() 方法@Overridepublic void display() {System.out.println("Child's overridden display method");}
}// 主类
public class Main {public static void main(String[] args) {// 创建子类对象Child child = new Child();// 调用子类重写的方法child.display(); // 输出: Child's overridden display method}
}

2.4 this和super关键字

thissuper 是两个关键字,用于引用当前对象和父类对象。它们在面向对象编程中有着不同的用途和作用域。

this 关键字

  1. 访问当前对象的属性和方法

    • 可以通过 this 关键字访问当前对象的属性和方法,避免命名冲突或者明确指出正在使用的对象是当前对象。
    class MyClass {private int number;public void setNumber(int number) {this.number = number; // 使用this访问当前对象的number属性}public int getNumber() {return this.number; // 使用this访问当前对象的number属性}
    }
    
  2. 在构造方法中调用其他构造方法

    • 可以使用 this() 调用本类的其他构造方法(必须位于构造方法的第一行)。
    class MyClass {private int number;// 构造方法1public MyClass() {this(0); // 调用另一个构造方法}// 构造方法2public MyClass(int number) {this.number = number;}
    }
    

super 关键字

  1. 访问父类的属性和方法

    • 可以使用 super 关键字访问父类中的属性和方法,特别是在子类中覆盖(重写)父类方法时,可以使用 super 调用父类的方法。
    class Parent {private int number;public Parent(int number) {this.number = number;}public void display() {System.out.println("Number: " + number);}
    }class Child extends Parent {public Child(int number) {super(number); // 调用父类的构造方法}@Overridepublic void display() {super.display(); // 调用父类的display方法System.out.println("Child's display method");}
    }
    
  2. 调用父类的构造方法

    • 可以使用 super() 调用父类的构造方法,必须位于子类构造方法的第一行。
    class Parent {private int number;public Parent(int number) {this.number = number;}
    }class Child extends Parent {public Child(int number) {super(number); // 调用父类的构造方法}
    }
    
  3. 避免子类和父类同名字段的歧义

    • 在子类和父类中有同名字段时,可以使用 super 关键字访问父类中的字段,以避免歧义。
    class Parent {protected int number = 10;
    }class Child extends Parent {private int number = 20;public void display() {System.out.println("Child's number: " + number); // 输出20System.out.println("Parent's number: " + super.number); // 输出10}
    }
    

区别和总结

  • this 关键字用于引用当前对象,可以访问当前对象的属性、方法和构造方法。
  • super 关键字用于引用父类对象,可以访问父类的属性、方法和构造方法。

在这里插入图片描述
如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/343306.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ AVL树 详细讲解

目录 一、AVL树的概念 二、AVL树的实现 1.AVL树节点的定义 2.AVL树的插入 3.AVL树的旋转 4.AVL树的验证 三、AVL树的性能 四、完结撒❀ 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率,但 如果数据有序或接近有序二叉搜索树将退化为单支树,查 …

容器化实践:DevOps环境下的容器交付流程

DevOps的兴起是为了应对市场和消费者对技术应用的不断增长的需求。它的目标是构建一个更快的开发环境,同时保持软件的高质量标准。DevOps还致力于在敏捷开发周期中提升软件的整体品质。这一目标的实现依赖于多种技术、平台和工具的综合运用。 结合容器化技术与DevO…

Xamarin.Android实现通知推送功能(1)

目录 1、背景说明1.1 开发环境1.2 实现效果1.2.1 推送的界面1.2.2 推送的设置1.2.3 推送的功能实现1.2.3.1、Activity的设置【重要】1.2.3.2、代码的实现 2、源码下载3、总结4、参考资料 1、背景说明 在App开发中,通知(或消息)的推送&#x…

jadx-gui-1.5 反编译工具使用教程 反混淆 Java android 查看签名

JADX:JADX是一个强大的反编译工具,它支持命令行和图形界面操作。除了基本的反编译功能外,JADX还提供了反混淆功能,有助于提高反编译后代码的可读性。 在Android开发和安全分析领域,反编译工具扮演着至关重要的角色。这…

HTML静态网页成品作业(HTML+CSS)—— 金宝贝儿童教育机构介绍网页(2个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有2个页面。 二、作品演示 三、代…

【数据分享】中国高技术产业统计年鉴(2023年)

大家好!今天我要向大家介绍一份重要的高技术产业发展情况统计数据资源——《中国高技术产业统计年鉴》。这份年鉴涵盖了从2023年中国高技术产业发展情况的全面数据,并以多格式提供免费下载。(无需分享朋友圈即可获取) 数据介绍 …

离散数学答疑 3

~A:A的补集 有时候空集是元素,有时候就是纯粹的空集 A-B的定义: 笛卡尔积: 求等价关系:先求划分再一一列举 不同划分:分几块。一块:两块:三块:分别计算 Ix是…

LeetCode62不同路径

题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径? …

【Spring Cloud Alibaba】开源组件Sentinel

目录 什么是Sentinel发展历史与Hystrix的异同 Sentinel可以做什么?Sentinel的功能Sentinel的开源生态Sentinel的用户安装Sentinel控制台预备环境准备Sentinel 分为两个部分:下载地址 项目集成Sentinel创建项目修改依赖信息添加启动注解添加配置信息在控制器类中新增…

Django 里的表格内容做修改

当Django里表格内容需要做修改&#xff0c;可以这么操作。 先看效果图 修改后的表格 1. 先得在 asset_list.html 里修改。你们的html有可能跟我不一样 <table border"1px"><thead><tr><th>ID</th><th>标题</th><th…

九种mfc140u.dll丢失的解决方法,全面解决mfc140u.dll文件丢失

mfc140u.dll是 Microsoft Visual C 2015 Redistributable 的一部分&#xff0c;它与 Microsoft 基础类库&#xff08;MFC&#xff09;的 Unicode 版本有关。当您在运行使用 Visual C 2015 开发的应用程序时&#xff0c;可能会碰到关于mfc140u.dll丢失的错误。下面列出了一些解决…

探索k8s集群的配置资源(secret和configmap)

目录 ConfigMap ConfigMap&#xff08;主要是将配置目录或者文件挂载到k8s里面使用&#xff09; 与Secret类似&#xff0c;区别在于ConfigMap保存的是不需要加密配置的信息。&#xff08;例如&#xff1a;配置文件&#xff09; ConfigMap 功能在 Kubernetes1.2 版本中引入&…

Python深度学习基于Tensorflow(13)目标检测实战

文章目录 RPN 整体代码RPN 具体实现过程数据标注读取标注数据固定图片大小调整目标框使用预训练模型获取 feature_shape定义 RPN 网络生成RPN 的 CLS 和 REG 数据集获取所有的锚点计算锚点与目标框的IOU 定义 RPN loss 和 训练过程 参考资料 这里实现的是二阶段目标检测&#x…

Linux系统下 安装 Nginx

一、下载Nginx安装包 压缩包下载地址&#xff1a;nginx: download 服务器有外网&#xff0c;可直接使用命令下载 wget -c https://nginx.org/download/nginx-1.24.0.tar.gz 二、安装Nginx 1、解压 tar -zxvf nginx-1.24.0.tar.gz 2、安装Nginx所需依赖 yum install -y gc…

线性代数|机器学习-P1课程简介

文章目录 1. 书籍下载2. 正文 1. 书籍下载 链接&#xff1a;https://pan.baidu.com/s/1QbK0enLh0x4nU1c4Tqwlkw 提取码&#xff1a;r7ft 本课程回顾线性代数在概率论、统计学、优化和深度学习中的应用。是GILBERT STRANG教授的有一个经典的课程。课程将线性代数分为如下部分&a…

【第二节】C/C++数据结构之线性表

目录 一、线性表基本说明 1.1 基本概念 1.2 抽象数据类型 1.3 存储结构 1.4 插入与删除的区别 1.5 顺序存储和链式存储的优缺点 二、链表 2.1 基本概念 2.2 抽象数据类型 2.3 单链表的定义 2.4 单链表的基本操作 2.5 单链表模板形式的类定义与实现 三、单向循环链…

探索未来制造,BFT Robotics引领潮流

“买机器人&#xff0c;上BFT” 在这个快速变化的时代&#xff0c;创新和效率是企业发展的关键。BFT Robotics&#xff0c;作为您值得信赖的合作伙伴&#xff0c;专注于为您提供一站式的机器人采购和自动化解决方案。 产品系列&#xff1a; 协作机器人&#xff1a;安全、灵活、…

OpenShift 4 - OpenShift Service Mesh 3 预览

《OpenShift / RHEL / DevSecOps 汇总目录》 了解 OpenShift Service Mesh 3 的变化 OpenShift Service Mesh 是一套在 OpenShift 上安装部署、跟踪监控 Istio 运行环境的实现。红帽在 2023 年底推出了技术预览版的 OpenShift Service Mesh 3&#xff0c;它和目前的 OpenShif…

RERCS系统开发实战案例-Part01 快速启动面板创建新功能启动面板

需求背景&#xff1a;RERCS系统设计合同应收付比例调整界面&#xff0c;目的为合同与应收付款调整关联&#xff0c;保证数据的完整性与准确性。 步骤① 参数化快速启动板事务码 &#xff1a;LPD_CUST_PARAM 选择对应的角色与实例 可以看到系统中的快速启动面板菜单中已有的功能…

顶顶通呼叫中心中间件-asr录音路径修改(mod_cti基于FreeSWITCH)

顶顶通呼叫中心中间件-asr录音路径修改(mod_cti基于FreeSWITCH) 录音路径模板。如果不是绝对路径&#xff0c;会把这个路径追加到FreeSWITCH的recordings后面。支持变量&#xff0c;比如日期 ${strftime(%Y-%m-%d)}。最后一个录音文件路径会保存到变量 ${cti_asr_last_record_…