Java继承教程!(o|o)

news2024/11/16 5:57:15

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 class
    Manager mgr = new Manager();

    // Set the name of the manager
    mgr.setName("Tom");

    // Get the name of the manager
    String mgrName = mgr.getName();

    // Display the manager name
    System.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 names
    printName(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 class
    super.print();
    // Print a message
    System.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 compiler
    System.out.println("Inside CSuper() constructor.");
  }
}

class CSub extends CSuper {
  public CSub() {
    super(); // Injected by the compiler
    System.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 class
  private int num = 200;

  // Hides name field in MySuper class
  private 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 class
  private int num = 200;

  // Hides the name field in MySuper class
  private 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.coloradmin.cn/o/2155856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux-gcc/g++

系列文章目录 C语言中的编译和链接 文章目录 系列文章目录一、编译过程gcc如何完成过程在这里涉及到一个重要的概念:函数库 二、动态库、静态库2.1 函数库一般分为静态库和动态库两种。 三、gcc选项gcc选项记忆 一、编译过程 具体过程在这一片c语言文章中讲解过:C语言中的编…

shardingjdbc分库分表原理

一 Mysql的瓶颈 二 解决方案 三 hash环算法 四 雪花算法

CCF csp认证 小白必看

c支持到C17(还是更高?)&#xff1b;所以学一些封装好的函数功能是必要的---比如STL里的函数&#xff1b; 因为可携带纸质资料&#xff0c;建议打印带入&#xff0c;需要时可翻阅。 【题目概述:】 0-devc环境配置 配置好你常用的编译版本&#xff1a; 想要调试记得开启下选…

分布式系统的CAP原理

CAP 理论的起源 CAP 理论起源于 2000 年&#xff0c;由加州大学伯克利分校的 Eric Brewer 教授在分布式计算原理研讨会&#xff08;PODC&#xff09;上提出&#xff0c;因此 CAP 定理又被称作布鲁尔定理&#xff08;Brewer’s Theorem&#xff09;。2002 年&#xff0c;麻省理…

「OC」引用计数(一)

iOS学习 前言自动引用计数引用计数引用计数的思考方式自己生成的对象&#xff0c;自己持有非自己生成的对象&#xff0c;自己也能持有不再需要自己持有的对象时释放无法释放非自己持有的对象 总结 前言 在学习oc时对引用计数略有了解&#xff0c;现在进行系统的学习总结。 自动…

力扣 无重复字符的最长子串

无重复字符的最长子串 https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/ 题目描述 题目分析 寻找无重复字符子串&#xff0c;首先要求是子串&#xff0c;然后是无重复 子串可以用滑动窗口确定 问题在于如何确定无重复 如果用暴力枚…

Java笔试面试题AI答之设计模式(5)

文章目录 21. 简述Java什么是适配器模式 ?适配器模式的主要组成部分包括&#xff1a;适配器模式的实现方式主要有两种&#xff1a;适配器模式的优点&#xff1a;适配器模式的缺点&#xff1a;示例说明&#xff1a; 22. 请用Java代码实现适配器模式的案例 &#xff1f; 21. 简述…

01 基础request

目录 类 WxRequest 的定义 静态属性 default 构造函数 constructor 方法 request HTTP 方法封装 创建 WxRequest 实例并导出 完整代码&#xff1a; 类 WxRequest 的定义 创建一个 WxRequest 类包含一个静态属性 default 和几个方法&#xff0c;用于处理网络请求。 静态…

Kotlin编程全攻略:从基础到实战项目的系统学习资料

Kotlin作为一种现代、简洁的编程语言&#xff0c;正逐渐成为Android开发的新宠。本文将为您介绍一套全面的Kotlin学习资料&#xff0c;包括学习大纲、PDF文档、源代码以及配套视频教程&#xff0c;帮助您从Kotlin的基础语法到实战项目开发&#xff0c;系统地提升您的编程技能。…

jetlinks物联网平台学习2(加盐算法登陆)

加盐算法 加盐算法加密验证密码是否正确 对于传统的MD5加密&#xff0c;比更传统的直接保存账号密码稍微安全一点。 md5加密是一种hash算法 比如对于123456来说&#xff0c;md5算法结果一定是e10adc3949ba59abbe56e057f20f883e 这个结果是固定的。于是有的人准备一张彩虹表 预先…

vscode 配置django

创建运行环境 使用pip安装Django&#xff1a;pip install django。 创建一个新的Django项目&#xff1a;django-admin startproject myproject。 打开VSCode&#xff0c;并在项目文件夹中打开终端。 在VSCode中安装Python扩展&#xff08;如果尚未安装&#xff09;。 在项…

SpringCloud-07 GateWay01 网关技术

Spring Cloud Gateway组件的核心是一系列的过滤器&#xff0c;通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。 Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器&#xff0c;隐藏微服务结点IP端口信息&#xff0c;从而加强安全保护。Spring Clou…

基于SpringBoot+Vue的高校门禁管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目源码、Python精…

长亭WAF绕过测试

本文的Bypass WAF 的核心思想在于&#xff0c;一些 WAF 产品处于降低误报考虑&#xff0c;对用户上传文件的内 容不做匹配&#xff0c;直接放行 0、环境 环境&#xff1a;两台服务器&#xff0c;一台配置宝塔面板&#xff0c;一台配置长亭雷池WAF 思路主要围绕&#xff1a;m…

Python | Leetcode Python题解之第423题从英文中重建数字

题目&#xff1a; 题解&#xff1a; class Solution:def originalDigits(self, s: str) -> str:c Counter(s)cnt [0] * 10cnt[0] c["z"]cnt[2] c["w"]cnt[4] c["u"]cnt[6] c["x"]cnt[8] c["g"]cnt[3] c["h…

DAY78服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE 漏洞

知识点&#xff1a; 1、数据库-Redis-未授权RCE&CVE 2、数据库-Couchdb-未授权RCE&CVE 3、数据库-H2database-未授权RCE&CVE 前置知识 1、复现环境&#xff1a;Vulfocus(官方在线的无法使用&#xff0c;需要自己本地搭建) 官方手册&#xff1a;https://fofapr…

20240922 每日AI必读资讯

OpenAI 首席科学家 MIT演讲&#xff01; - 揭示 o1模型训练核心秘密&#xff1a; 通过激励模型学习是培养 AGI 系统通用技能的最佳方式。 - 提出了类比“教人钓鱼”的方式&#xff0c;强调激励学习的重要性&#xff1a;“授人以鱼&#xff0c;不如授人以渔”&#xff0c;但是…

机器视觉OpenCV

1. 环境配置 1.1 安装Python https://www.python.org/downloads/windows/ python-3.9.13-amd64 pip下载加速&#xff1a; pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip config set install.trusted-host mirrors.aliyun.com1.2 安装Ope…

串口RS232,485

RS232和RS485都是串口通信的变种 TTL 串口的波特率/频率&#xff1a;9600&#xff0c;115200等&#xff0c;表示在1s内&#xff0c;串口可以传输9600个高低电平 那串口通信时&#xff0c;高低电压的范围&#xff1a;TTL电平 TTL 的电平标准&#xff0c;理想状态下&#xff0…

通信工程学习:什么是NFV网络功能虚拟化

NFV&#xff1a;网络功能虚拟化 NFV&#xff08;Network Function Virtualization&#xff09;&#xff0c;即网络功能虚拟化&#xff0c;是一种通过虚拟化技术实现网络功能的技术手段。它借鉴了x86服务器的架构&#xff0c;将传统的网络硬件设备如路由器、交换机、防火墙、负载…