javascript动态绑定

news2024/10/6 14:32:36

介绍

先来看看ai的解释

动态绑定机制是面向对象编程中的一个核心概念,特别是在Java这样的语言中。它允许在运行时根据对象的实际类型来决定调用哪个方法,而不是在编译时。这是多态性的关键特性之一。
在Java中,动态绑定是通过方法调用和方法执行的两个阶段来实现的:
1. **方法调用**:当调用一个对象的方法时,JVM(Java虚拟机)会查看对象的实际类型来决定哪个方法实现应该被调用。如果这个方法在对象的类中被重写,JVM会调用这个重写的方法。这个过程发生在运行时,因为它需要考虑对象的具体类型。
2. **方法执行**:一旦JVM确定了要调用的方法,它就会执行这个方法。在这个过程中,JVM会使用对象的实际类型来查找和执行正确的方法。
动态绑定的关键在于,它允许子类提供特定于自己类型的行为,即使是通过父类的引用来调用方法。这意味着,如果你有一个父类引用指向一个子类对象,当通过这个引用调用一个方法时,实际执行的是子类中定义的那个版本的方法(如果子类重写了这个方法的话)。
为了使动态绑定工作,Java使用了 invokevirtual 指令,这是Java字节码指令集的一部分。当JVM执行 invokevirtual 指令时,它会动态地确定应该调用哪个方法。
这里有一个简单的例子来说明动态绑定:
```java
class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}
class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
}
public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 创建一个Dog对象的引用,但是引用类型是Animal
        animal.sound(); // 这将调用Dog类中的sound方法,输出 "Dog barks"
    }
}
```
在这个例子中,尽管 `animal` 的引用类型是 `Animal`,但是实际的对象是 `Dog` 类型。因此,当调用 `animal.sound()` 方法时,会动态绑定到 `Dog` 类的 `sound` 方法,输出 "Dog barks"。这就是动态绑定的魔力所在。
 

个人理解,这里还是离不开我们的编译类型和运行类型。动态绑定是绑定我们的运行类型,并且只对方法进行执行。对于属性则是在哪个类声明就用属性

实操代码

父类和子类

package hansunping;

//创建父类
public class person {
  //简单的创建两个属性
  private String name;
  private int age;

  //创建行为方法,方法中调用创建的say方法
  public void haviours(){
      say();
  }
  //创建方法
  public void say(){
      System.out.println("我是人类!!!");
  }

}
//blog.csdn.net/YYniannian/article/details/126222600
//创建子类
class Student extends person {//如果没有指定访问修饰符,默认情况下该类具有包私有(package-priva
	//te)访问级别,这意味着它只能在同一个包(package)内被访问。
  //创建学生的属性
  private int  score;
  //重写行为
//  public void haviours(){
//      say();
//  }
  //重写say方法
  public void say(){
      System.out.println("我是学生!!!");
  }
}

分析,我们可以从这里看到父类有haviours,say方法。子类同样有haviour方法和say方法。并且haviour方法调用了say方法。

主类

我们在主类中

package hansunping;

public class demon1 {
	public static void main(String[] args) {
		 person student = new Student();
	        //调用学生的say()方法,由于我们的编译类型是Person类,而运行类型是Student类,而动态绑定机制是绑定运行类型。
	        //所以,当我们调用say()方法时,是调用Student类的say()方法
	        student.haviours();//返回“我是学生”
	        //、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
	        //如果我们将student类的say()方法注销,他寻找student类的say方法无果后,会再向它的父类调用say方法。返回我是人类,效果等同于
	
	}

}

person student = new Student();

person是编译类型。student是运行类型。我们的动态绑定就是与运行类型有关的。

在不注释子类的haviour方法时运行结果为

我是学生!!!

在注释之后结果  还是我是学生!!!

为什么呢?

因为子类的haviou方法不存在。那么根据我们的多态的继承寻找规则,我们就找到了父类的haviou方法。在父类的haviou方法中也是调用了say方法的。那么这个say方法是父类的吗?不是,这个方法应该是子类的。即运行类型的类方法。这里要弄懂编译类型和运行类型

接下来我们看另外一个

代码

package hansunping;

//创建父类
public class person {
  //简单的创建两个属性
  private String name;
  private int age;
  public int i =10;
  public int sum() {
	  return getl()+10;	
}
  public int sum1() {
	  return i+10;	
}
  public int getl() {
	  return i;	
}



}
//blog.csdn.net/YYniannian/article/details/126222600
//创建子类
class Student extends person {//如果没有指定访问修饰符,默认情况下该类具有包私有(package-priva
	//te)访问级别,这意味着它只能在同一个包(package)内被访问。
  //创建学生的属性
	  public int i =10;
	  public int sum() {
		  return getl()+20;	
	}
	  public int sum1() {
		  return i+10;	
	}
	  public int getl() {
		  return i;	
	}

}

主类


public class demon1 {
	public static void main(String[] args) {
		 person student = new Student();
	        //调用学生的say()方法,由于我们的编译类型是Person类,而运行类型是Student类,而动态绑定机制是绑定运行类型。
	        //所以,当我们调用say()方法时,是调用Student类的say()方法
//	        student.haviours();//返回“我是学生”
		 System.out.println(student.sum());
		 System.out.println(student.sum1());
	        //、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
	        //如果我们将student类的say()方法注销,他寻找student类的say方法无果后,会再向它的父类调用say方法。返回我是人类,效果等同于
	
	}

}

运行结果

30

20

好,现在我们同样注释掉子类的sum方法

结果

20

20

那么20是怎么来的,分析一下。student从子类中找不到sum方法,所以从父类找。父类有

  public int sum() {
	  return getl()+10;	
}

这个,那么这个get1()+10中的getl是父类的还是子类的方法呢?我将父类的

public int i =20;

i为20.如果是父类的话 那么应该是30了。动态绑定即允许环境还是在子类那里。而编译类型是个引用了,这个时候我们要看内存地址而不是指向的引用

我再在子类中添加;

public int getl() {

return i+1000;

}

结果为

1020

20

我们来验证下属性,我将子类的

public int sum() {

return i+30;

}

改成了i+30,发现结果为50

50

20.说明属性还是不变了

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

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

相关文章

C#——枚举类型详情

枚举类型 枚举类型(也可以称为“枚举器”)由一组具有独立标识符(名称)的整数类型常量构成,在 C# 中枚举类型不仅可以在类或结构体的内部声明,也可以在类或结构体的外部声明,默认情况下枚举类型…

ViT:2 理解CLIP

大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技(Mamba,xLSTM,KAN)则提…

大模型基础——从零实现一个Transformer(2)

大模型基础——从零实现一个Transformer(1) 一、引言 上一章主要实现了一下Transformer里面的BPE算法和 Embedding模块定义 本章主要讲一下 Transformer里面的位置编码以及多头注意力 二、位置编码 2.1正弦位置编码(Sinusoidal Position Encoding) 其中: pos&…

linux中xterm窗口怎么调整字体大小

需求:打开的xterm窗口字体比较小,怎么才能调整字体大小,打开的大写: 解决方法: 在home目录下搞一个设置文件 .Xresource,里面内容如下 然后把设置文件添加到 .tcshrc 文件中生效 这样重新打开的xterm字…

MySQL数据库(二)和java复习

一.MySQL数据库学习(二) (一).DQL查询数据 DQL(Data Query Language)是用于从数据库中检索数据的语言。常见的 DQL 语句包括 SELECT、FROM、WHERE、GROUP BY、HAVING 和 ORDER BY 等关键字,用于指定要检索的数据、数据源、过滤条件、分组方…

《编程小白变大神:DjangoBlog带你飞越代码海洋》

还在为你的博客加载速度慢而烦恼?DjangoBlog性能优化大揭秘,让你的网站速度飞跃提升!本文将带你深入了解缓存策略、数据库优化、静态文件处理等关键技术,更有Gunicorn和Nginx的黄金搭档,让你的博客部署如虎添翼。无论你…

助力高考,一组彩色的文字

1、获取文本内容 首先&#xff0c;获取每个<div>元素的文本内容&#xff0c;并清空其内部HTML&#xff08;innerHTML ""&#xff09;。 2、创建<span>元素 然后&#xff0c;它遍历文本的每个字符&#xff0c;为每个字符创建一个新的<span>元素…

《python程序语言设计》2018版第5章第36题改造4.17 石头 剪刀 布某一方超过2次就结束。

代码编写记录 2024.05.04 05.36.01version 换一个什么数代替剪子 我先建立一个函数judgement condition 石头3 剪子2 布1 如何构建一个循环进行的架构&#xff0c;是我们最需要的想法 循环以什么条件开始呢 是小于2个还是大于2个。 guess_num random.randint(1, 3) computer…

nginx优化与防盗链【☆☆☆】

目录 一、用户层面的优化 1、隐藏版本号 方法一&#xff1a;修改配置文件 方法二&#xff1a;修改源码文件&#xff0c;重新编译安装 2、修改nginx用户与组 3、配置nginx网页缓存时间 4、nginx的日志切割 5、配置nginx实现连接超时 6、更改nginx运行进程数 7、开启网…

IPv4 子网掩码计算器—python代码实现

今天聊一下&#xff0c;我用python和vscode工具实现一个IPv4计算器的一些思路&#xff0c;以及使用Python编写IPv4计算器一些好处&#xff1f; 首先&#xff0c;一、Python语法简洁易读&#xff0c;便于理解和维护&#xff0c;即使对编程不熟悉的用户也能快速了解代码逻辑。其…

阿里通义千问 Qwen2 大模型开源发布

阿里通义千问 Qwen2 大模型开源发布 Qwen2 系列模型是 Qwen1.5 系列模型的重大升级。该系列包括了五个不同尺寸的预训练和指令微调模型&#xff1a;Qwen2-0.5B、Qwen2-1.5B、Qwen2-7B、Qwen2-57B-A14B 以及 Qwen2-72B。 在中文和英文的基础上&#xff0c;Qwen2 系列的训练数…

已解决Error || RuntimeError: size mismatch, m1: [32 x 100], m2: [500 x 10]

已解决Error || RuntimeError: size mismatch, m1: [32 x 100], m2: [500 x 10] 原创作者&#xff1a; 猫头虎 作者微信号&#xff1a; Libin9iOak 作者公众号&#xff1a; 猫头虎技术团队 更新日期&#xff1a; 2024年6月6日 博主猫头虎的技术世界 &#x1f31f; 欢迎来…

情景题之小明的Linux实习之旅:linux实战练习1(下)【基础命令,权限修改,日志查询,进程管理...】

小明的Linux实习之旅&#xff1a;基础指令练习情景练习题下 前景提要小明是怎么做的场景1&#xff1a;初识Linux&#xff0c;创建目录和文件场景2&#xff1a;权限管理&#xff0c;小明的权限困惑场景3&#xff1a;打包与解压&#xff0c;小明的备份操作场景4&#xff1a;使用G…

分享一个 .NET Core Console 项目中应用 NLog 写日志的详细例子

前言 日志在软件开发中扮演着非常重要的角色&#xff0c;通常我们用它来记录应用程序运行时发生的事件、错误信息、警告以及其他相关信息&#xff0c;帮助在调试和排查问题时更快速地定位和解决 Bug。 通过日志&#xff0c;我们可以做到&#xff1a; 故障排除和调试&#xff…

让GNSSRTK不再难【第一天】

第1讲 GNSS系统组成以及应用 北斗导航科普动画_哔哩哔哩_bilibili 1.1 GNSS系统 1.1.1 基本概念 全球卫星导航系统&#xff08;Global Navigation Satellite System, GNSS&#xff09;&#xff0c;是能在地球表面或近地空间的任何地点为用户提供全天候的三维坐标、速度以及…

ISO 19115-2:2019 第6章 获取和处理元数据

6 获取和处理元数据 6.1 获取和处理要求的元数据 ISO 19115-1 确定了描述数字地理资源所需的元数据。本文件扩展了 ISO 19115-1 中确定的元数据,并确定了描述地理资源获取和处理所需的附加元数据。 6.2 获取和处理元数据包及其依赖关系 ISO 地理信息系列标准使用一个或多个…

【C语言】C语言—通讯录管理系统(源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

算法笔记1-高精度模板(加减乘除)个人模板

目录 加法 减法 乘法 ​编辑 除法 加法 #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue>using namespace std;typedef pair<int,int> PII;const int N 1e5 10;int n; int a[N],…

nw.js 如何调用activeX控件 (控件是C++编写的dll文件)

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…