Java继承教程!(o|o)

Java 继承

Java面向对象设计 - Java继承

子类可以从超类继承。超类也称为基类或父类。子类也称为派生类或子类。

从另一个类继承一个类非常简单。我们在子类的类声明中使用关键字extends,后跟超类名称。

Java不支持多重继承的实现。

Java中的类不能有多个超类。

语法

一般的语法是

<class modifiers>class <SubclassName> extends <SuperclassName> {// Code for the   Subclass
}

例子

以下代码显示如何使用从Employee类创建Manager类。

class Employee {private String name = "Unknown";public void setName(String name) {this.name = name;}public String getName() {return name;}
}
class Manager extends Employee {
}
public class Main {public static void main(String[] args) {// Create an object of the Manager classManager mgr = new Manager();// Set the name of the managermgr.setName("Tom");// Get the name of the managerString mgrName = mgr.getName();// Display the manager nameSystem.out.println("Manager Name: " + mgrName);}
}

上面的代码生成以下结果。

注意

我们没有为Manager类编写任何代码,它的工作原理与Employee类相同,因为它继承自Employee类。

您可以使用Manager类的构造函数创建一个管理器对象。

Manager mgr = new Manager();

创建管理器对象后,Manager对象的工作方式与Employee对象相同。

我们对manager对象使用了setName()和getName()方法。

mgr.setName("Tom"); 
String mgrName  = mgr.getName();

Manager类不声明setName()和getName()方法。Manager类“扩展Employee"。

当一个类从另一个类继承时,它继承它的超类成员,实例变量,方法等。

对象父类

对象类是默认超类。

所有类都隐式继承自Object类。因此所有类的对象都可以使用Object类的方法。

public class P {}

类P从Object扩展,即使我们没有指定父类。

Object类声明了hashCode()和toString()方法。因为Employee类是Object类的一个子类,它可以使用这些方法。

Employee emp = new Employee();
int hc  = emp.hashCode(); 
String str = emp.toString();

Employee类不使用extends子句指定其超类。这意味着它继承自Object类。

Object类声明了hashCode()和toString()方法。因为Employee类是Object类的一个子类,它可以使用这些方法。

向上转换和向下转换

现实世界中的“is-a”关系在软件中转化为继承类层次结构。

例如,Manager是特定类型的Employee。 Employee是一种特定类型的Object。

当您在继承层次结构中向上移动时,将从特定类型移动到更一般的类型。

从子类到超类的赋值称为上转换,它在Java中始终允许。

class Employee {private String name = "Unknown";public void setName(String name) {this.name = name;}public String getName() {return name;}
}class Manager extends Employee {
}public class Main {public static void printName(Employee emp) {String name = emp.getName();System.out.println(name);}public static void main(String[] args) {Employee emp = new Employee();emp.setName("Tom");Manager mgr = new Manager();mgr.setName("Jack"); // Inheritance of setName() at work// Print namesprintName(emp);printName(mgr); // Upcasting at work}
}

为子类变量分配超类引用称为向下转换。

向下转换与向上转换相反。

在向上转换中,赋值向上移动类层次结构,而在向下转换中,赋值向下移动类层次结构。

我们必须在向下转换中使用类型转换。

Manager mgr = (Manager)emp;  // OK. Downcast  at work

上面的代码生成以下结果。

instanceof运算符

Java instanceof运算符帮助我们确定引用变量是否有对类或子类的引用。

它需要两个操作数,并计算为布尔值true或false。

它的语法是

<Class Reference Variable> instanceof <Class Name or Interface>

如果<Class Reference Variable>引用类<Class Name>或其任何后代的对象,instanceof返回true。

如果引用变量为null,instanceof总是返回false。

我们应该在向下转换之前使用instanceof运算符。

Manager mgr = new Manager(); 
Employee emp = mgr;
if (emp instanceof Manager)  {// downcast  will succeed mgr = (Manager)emp;
}else  {// emp is not  a  Manager type
}

禁用继承

我们可以通过声明类final来禁用子类。

最终的类不能被子类化。

下面的代码声明了一个名为MyClass的最终类:

public final  class  MyClass{}

我们也可以声明一个方法为final。最终方法不能被子类覆盖或隐藏。

public class A  {public final  void  m1()  {}public void  m2()  {}
}

Java 方法重写

Java面向对象设计 - Java方法重写

方法重写

重新定义从超类继承的类中的实例方法称为方法重写。

例子

让我们考虑类A和类B的以下声明:

public class A  {public void  print() { System.out.println("A");}
}public class B  extends A  {public void  print() { System.out.println("B");}
}

类B是类A的子类。类B从其超类继承print()方法并重新定义它。

类B中的print()方法覆盖类A的print()方法。

如果一个类覆盖了一个方法,它会影响覆盖的类及其子类。考虑下面的类C的声明:

public class C  extends B  {// Inherits B.print()
}

类C不声明任何方法。它继承类B中的print()方法。

注意

类总是继承它的直接超类的可用的。

方法必须是实例方法。重写不适用于静态方法。

重写方法必须具有与重写方法相同的名称。

重写方法必须具有与重写方法相同顺序的相同类型的相同数量的参数。

当方法的参数使用通用类型时,考虑通用类型参数的擦除,而不是通用类型本身与其他方法比较。

参数的名称无关紧要。

如果重写方法的返回类型是引用类型,则重写方法的返回类型必须与重写方法的返回类型兼容。

访问级别

重写方法的访问级别必须至少与重写方法的访问级别相同或更宽松。

下表列出了重写方法允许的访问级别

重写方法访问级别允许重写方法访问级别...
publicpublic
protectedpublic, protected
package-levelpublic, protected, package-level

方法可以在其throws子句中包括检查异常的列表。重写方法无法向重写方法中的异常列表添加新的异常。

它可以删除一个或所有异常,或者可以用另一个异常替换异常。

访问重写方法

从子类访问重写的方法。子类可以使用关键字 super 作为限定符来调用超类的重写方法。

class MySuperClass {public void print() {System.out.println("Inside MySuperClass");}
}class MySubClass extends MySuperClass {public void print() {// Call print() method of MySuperClass classsuper.print();// Print a messageSystem.out.println("Inside MySubClass.print()");}public void callOverridenPrint() {// Call print() method of MySuperClass class super.print();}
}public class Main {public static void main(String[] args) {MySubClass aoSub = new MySubClass();aoSub.print();aoSub.callOverridenPrint();}
}

上面的代码生成以下结果。

Java 继承和构造函数 

Java面向对象设计 - Java继承和构造函数

构造函数不是类的成员,它们不是由子类继承的。

它们用于初始化实例变量。

class CSuper {public CSuper() {System.out.println("Inside CSuper() constructor.");}
}class CSub extends CSuper {public CSub() {System.out.println("Inside CSub()  constructor.");}
}public class Main {public static void main(String[] args) {CSub cs = new CSub();}
}

上面的代码生成以下结果。

例子

下面显示了如何编译器注入一个super()来立即调用父类的无参数构造函数。

class CSuper {public CSuper() {super(); // Injected by the compilerSystem.out.println("Inside CSuper() constructor.");}
}class CSub extends CSuper {public CSub() {super(); // Injected by the compilerSystem.out.println("Inside CSub()  constructor.");}
}public class Main {public static void main(String[] args) {CSub cs = new CSub();}
}

上面的代码生成以下结果。

关键字super指的是类的直接父类。

我们可以调用超类构造函数,只使用super关键字作为构造函数中的第一个语句。

无参数构造函数

我们可以将超类的no-args构造函数或任何其他构造函数显式地调用为类的构造函数中的第一个语句。

只有在没有明确添加的情况下,编译器才会注入no-args构造函数调用。

class Employee {private String name = "Unknown";public Employee(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}
}class Manager extends Employee {public Manager(String name) {super(name);}
}public class Main {public static void main(String[] args) {Manager mgr = new Manager("Tom");String name = mgr.getName();System.out.println("Manager name:  " + name);}
}

上面的代码生成以下结果。

每个类都必须直接或间接地从其构造函数中调用其超类的构造函数。

如果超类没有no-args构造函数,我们必须显式地调用超类的任何其他构造函数。

Java 继承隐藏

Java面向对象的设计 - Java继承隐藏

方法隐藏

类从其超类继承所有非私有静态方法。

重定义类中继承的静态方法称为方法隐藏。

子类中的重定义静态方法隐藏其超类的静态方法。

在类中重定义非静态方法称为方法覆盖。

关于方法隐藏的重定义方法(名称,访问级别,返回类型和异常)的所有规则与方法覆盖相同。

class MySuper {public static void print() {System.out.println("Inside MySuper.print()");}
}class MySubclass extends MySuper {public static void print() {System.out.println("Inside MySubclass.print()");}
}public class Main {public static void main(String[] args) {MySuper mhSuper = new MySub();MySubclass mhSub = new MySubclass();MySuper.print();MySubclass.print();((MySuper) mhSub).print();mhSuper = mhSub;mhSuper.print();((MySubclass) mhSuper).print();}
}

上面的代码生成以下结果。

字段隐藏

类中的字段声明(静态或非静态)在其父类中隐藏具有相同名称的继承字段。

在字段隐藏的情况下,不考虑字段的类型及其访问级别。

字段隐藏仅基于字段名称。

class MySuper {protected int num = 100;protected String name = "Tom";
}class MySub extends MySuper {public void print() {System.out.println("num: " + num);System.out.println("name: " + name);}
}class MySub2 extends MySuper {// Hides num field in MySuper classprivate int num = 200;// Hides name field in MySuper classprivate String name = "Jack";public void print() {System.out.println("num: " + num);System.out.println("name: " + name);}
}public class Main {public static void main(String[] args) {MySub fhSub = new MySub();fhSub.print();MySub2 fhSub2 = new MySub2();fhSub2.print();}
}

上面的代码生成以下结果。

例子

以下代码显示了如何使用super关键字访问超类的隐藏字段

class MySuper {protected int num = 100;protected String name = "Tom";
}class MySub extends MySuper {// Hides the num field in MySuper classprivate int num = 200;// Hides the name field in MySuper classprivate String name = "Jack";public void print() {System.out.println("num: " + num);System.out.println("super.num: " + super.num);System.out.println("name: " + name);System.out.println("super.name: " + super.name);}
}public class Main {public static void main(String[] args) {MySub s = new MySub();s.print();}
}

上面的代码生成以下结果。

字段隐藏发生在一个类声明一个变量与来自其超类的继承变量具有相同名称的时候。

字段隐藏仅基于字段的名称。

类应该使用关键字super来访问超类的隐藏字段。

类可以使用简单的名称来访问其主体中的重定义字段

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

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

相关文章

CVE-2024-46101

前言 自己挖的第一个CVE~ 喜提critical 这里简单说一下。 漏洞简介 GDidees CMS < 3.9.1 的版本&#xff0c;存在一个任意文件上传漏洞。允许登录后的攻击者上传webshell获得网站的权限。 影响版本&#xff1a; GDidees CMS < 3.9.1 &#xff08;其它的我没测。。&am…

专题七_分治_快排_归并_算法专题详细总结

目录 分治 一、分治思想的概念 二、分治思想的步骤 1. 颜⾊分类&#xff08;medium&#xff09; 解析&#xff1a; 2. 快速排序&#xff08;medium&#xff09; 解析&#xff1a; 总结&#xff1a; 3. 快速选择算法&#xff08;medium&#xff09; 解析&#xff1a; …

xinference linux系统下部署

1.创建虚拟环境 conda create -n xinfer pyrhon3.10 2.使用虚拟环境 conda activate xinfer (xinfer) roothome:~$ python -V Python 3.10.14 3.pip安装环境 pip install "xinference[all]" 4.启动服务 nohup xinference-local --host 0.0.0.0 --port 9997 &…

认识结构体

目录 一.结构体类型的声明 1.结构的声明 2.定义结构体变量 3.结构体变量初始化 4.结构体的特殊声明 二.结构体对齐(重点难点) 1.结构体对齐规则 2.结构体对齐练习 (一)简单结构体对齐 (二)嵌套结构体对齐 3.为什么存在内存对齐 4.修改默认对齐数 三.结构体传参 1…

python新手的五个练习题

代码 # 1. 定义一个变量my_Number,将其设置为你的学号&#xff0c;然后输出到终端。 my_Number "20240001" # 假设你的学号是20240001 print("学号:", my_Number) # 2. 计算并输出到终端:两个数(例如3和5)的和、差、乘积和商。 num1 3 num2 5 print(&…

nacos适配人大金仓的数据库

前言 在微服务架构中&#xff0c;服务发现和配置管理是关键组件。Nacos作为一个动态服务发现和配置管理平台&#xff0c;支持多种数据库作为其后端存储。本文将探讨如何在Nacos中适配人大金仓数据库&#xff0c;以及在此过程中的最佳实践。 Nacos简介 Nacos&#xff08;Nami…

安卓数据存储——SharedPreferences

共享参数 SharedPreferences 1、sharedPreferences是Android的一个轻量级存储工具&#xff0c;采用的存储结构是key - value的键值对方式 2、共享参数的存储介质是符合XML规范的配置文件。保存路径是&#xff1a;/data/data/应用包名/shared_prefs/文件名.xml 使用场景&…

[Python学习日记-26] Python 中的文件操作

[Python学习日记-26] Python 中的文件操作 简介 操作模式 循环文件 其他功能 混合模式 修改文件 简介 在 Python 中的文件操作其实和我们平时使用的 Word 的操作是比较类似的&#xff0c;我们先说一下 Word 的操作流程&#xff0c;流程如下&#xff1a; 找到文件&#x…

LeetCode题练习与总结:回文链表--234

一、题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&#x…

【笔记】第三节 组织与性能

3.1 基本成分 3.2 微观组织特征 0.6-0.8C%碳素钢的组织为珠光体和少量的铁素体。 如何把组织和性能联系起来&#xff1f;德国克虏伯公司的研究——珠光体片间距与渗碳体片层厚度成比例&#xff1a; t s 0 ( ρ 15 ( C % ) − 1 ) ts_0(\frac{\rho}{15(C\%)}-1) ts0​(15(C%)…

go的结构体、方法、接口

结构体&#xff1a; 结构体&#xff1a;不同类型数据集合 结构体成员是由一系列的成员变量构成&#xff0c;这些成员变量也被称为“字段” 先声明一下我们的结构体&#xff1a; type Person struct {name stringage intsex string } 定义结构体法1&#xff1a; var p1 P…

谷歌收录批量查询,怎么查看批量查询谷歌收录情况

在SEO&#xff08;搜索引擎优化&#xff09;领域&#xff0c;确保网站内容被谷歌等搜索引擎有效收录是提升网站可见性和流量的关键步骤。批量查询谷歌收录情况&#xff0c;能够帮助网站管理员快速了解哪些页面已被搜索引擎识别并编入索引&#xff0c;哪些页面可能存在问题需要优…

SpringBoot项目License证书生成与验证(TrueLicense) 【记录】

SpringBoot项目License证书生成与验证(TrueLicense) 【记录】 在非开源产品、商业软件、收费软件等系统的使用上&#xff0c;需要考虑系统的使用版权问题&#xff0c;不能随便一个人拿去在任何环境都能用。应用部署一般分为两种情况&#xff1a; 应用部署在开发者自己的云服务…

变电站缺陷数据集8307张,带xml标注和txt标注,可以直接用于yolo训练

变电站缺陷数据集8307张&#xff0c; 带xml标注和txt标注&#xff0c;可以直接用于yolo训练&#xff0c;赠附五个脚本 变电站缺陷数据集 数据集概述 变电站缺陷数据集是一个专门针对变电站设备和环境缺陷检测的图像数据集。该数据集包含了8307张经过标注的图像&#xff0c;旨…

Java 入门指南:JVM(Java虚拟机)垃圾回收机制 —— 垃圾收集器

文章目录 垃圾回收机制Stop-the-World垃圾收集器垃圾收集器分类Serial 收集器Serial Old 收集器ParNew 收集器Parallel Scavenge 收集器Parallel Old 收集器CMS 收集器CMS 收集器缺点 G1 收集器G1 收集器特点G1 收集器的分代理念G1 收集器运作过程 垃圾回收机制 垃圾回收&…

【Linux笔记】如何将内容从一个文件复制到另一个文件

比如&#xff1a;将文件tmp_file.txt中的部分数据&#xff0c;复制到file01.txt中去 tmp_file.txt文中内容&#xff1a; file01.txt为空文档 一、使用vi编辑器 I、文件中直接使用:e 目标文件进行切换文件复制 1、打开被复制文件 vi tmp_file.txt 2、进入一般命令模式 默认情况为…

排序-----归并排序(递归版)

核心思想&#xff1a;假设数组前后两部分各自有序&#xff0c;然后各定义两个指针&#xff0c;谁小谁放到新开辟的数组里面&#xff0c;最后把新开辟的数组赋值给原数组就完成了。要使前后两部分有序就采用递归的方式&#xff0c;不断往下划分块&#xff0c;最后一层划分为两个…

SVM原理

SVM 这里由于过了很长时间 博主当时因为兴趣了解了下 博主现在把以前的知识放到博客上 作为以前的学习的一个结束 这些东西来自其他资料上 小伙伴看不懂英文的自行去翻译下吧 博主就偷个懒了 多维空间和低维空间 不一样的分法&#xff0c;将数据映射到高维 &…

鸿蒙OpenHarmony【轻量系统内核扩展组件(动态加载)】子系统开发

基本概念 在硬件资源有限的小设备中&#xff0c;需要通过算法的动态部署能力来解决无法同时部署多种算法的问题。以开发者易用为主要考虑因素&#xff0c;同时考虑到多平台的通用性&#xff0c;LiteOS-M选择业界标准的ELF加载方案&#xff0c;方便拓展算法生态。LiteOS-M提供类…

ZYNQ学习--AXI总线协议

一、AXI 总线简介 AXI&#xff08;Advanced Extensible Interface&#xff09;高级拓展总线是AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;高级微控制总线架构中的一个高性能总线协议&#xff0c;由ARM公司开发。AXI总线协议被广泛应用于高带宽、低…