【JAVA】Object类与抽象类

作者主页:paper jie_的博客

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。

本文录入于《JAVASE语法系列》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将javaSE基础知识一网打尽,希望可以帮到读者们哦。

其他专栏:《JAVA》《算法详解》《C语言》等

内容分享:本期将会对JAVA中的Object类和内部类进行讲解

目录

 

Object类

获取对象信息toString()方法

对象比较equals方法

 hashcode方法

内部类

内部类的分类

实例内部类

静态内部类

局部内部类 

匿名内部类 


Object类

Object类是java中默认提供的一个类。java里面除了Object类,其他全部的类都是会默认继承Object类的。所以所有的类的对象都可以用Object类的引用来接收。

举个栗子:

class Person{}
class Student{}
public class Test {public static void function(Object obj) {System.out.println(obj);
}public static void main(String[] args) {function(new Person());function(new Student());}}

在java开发的过程中,Objec类是参数的最高统一类型。但是Object类也存在有定义好的一些方法。

这些都是Object类定义好的方法:

这几个方法对于java学习来说是必须掌握,不可缺少的。

获取对象信息toString()方法

如果要打印对象中的内容,直接重写Object类的toSting方法即可:

// Object类中的toString()方法实现:public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}

其中的道理就是:object类是所有类的父类,重写了tostring方法后,在使用print方法时就会调用我们重写的toString方法以达到效果。

对象比较equals方法

在java中,==进行比较时:

要是两个比较对象是基本类型时,比较的是变量值是否相等

要是两个比较对象是引用类型变量时,比较的是引用地址是否相等

如果要比较对象中的内容,就必须重写Object类的equals方法,equals方法默认是按地址来比较的

// Object类中的equals方法public boolean equals(Object obj) {return (this == obj); // 使用引用中的地址直接来进行比较}
class Person{private String name ;private int age ;public Person(String name, int age) {this.age = age ;this.name = name ;}
}
public class Test {public static void main(String[] args) {Person p1 = new Person("qeo", 20) ;Person p2 = new Person("qeo", 20) ;int a = 10;int b = 10;System.out.println(a == b); // 输出trueSystem.out.println(p1 == p2); // 输出falseSystem.out.println(p1.equals(p2)); // 输出false}
}

上面比较的是地址,想要比较他们的内容就要重写equals方法:

class Person{
...@Overridepublic boolean equals(Object obj) {if (obj == null) {return false ;} if(this == obj) {return true ;} // 不是Person类对象if (!(obj instanceof Person)) {return false ;} Person person = (Person) obj ; // 向下转型,比较属性值return this.name.equals(person.name) && this.age==person.age ;}
}

所以要比较对象的内容是不是相同的时候,就一定要重写equals方法

 hashcode方法

通过观看toString方法的源码我们发现了里面有一个hashcode方法:

    public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}

它的作用就是帮助我们算一个具体的对象位置,它的结果是一个内存地址然后会调用toHexString方法,将这个地址以16进制来打印输出。

hashcode方法源码:

 public native int hashCode();

它是一个native方法,底层是用c/c++代码写的,在java中我们是看不到的。

在我们的认知中,两个名字相同,年龄相同的对象存储在同一个位置,但是不重写hashcode方法的话,结果是不同的:

class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}
}
public class TestDemo4 {public static void main(String[] args) {Person per1 = new Person("go", 20) ;Person per2 = new Person("go", 20) ;System.out.println(per1.hashCode());System.out.println(per2.hashCode());}
} //执行结果4601419581163157884

这时我们再重写hashcode方法:

class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;} @Overridepublic int hashCode() {return Objects.hash(name, age);}
}
public class TestDemo4 {public static void main(String[] args) {Person per1 = new Person("go", 20) ;Person per2 = new Person("go", 20) ;System.out.println(per1.hashCode());System.out.println(per2.hashCode());}
} //执行结果460141958460141958

这时发现他们的哈希值就是一样的了。

结论:

hashcode方法用来确定对象在内存中储存的位置相不相同。

hashcode在散列表中才有用,在散列表中hashcode的作用是获取对象的散列码,来确定对象在散列表中的位置。

内部类

当一个事物的内部,还有一部分需要一个完整的结构进行描述,而这个内部的完整的结构只要为外部的事物提供服务,那这个内部结构使用内部类。

在Java中,可以将一个类定义在另一个类或者方法的内部,前者称为内部类,后者称为外部类。

public class OutClass {class InnerClass{}
} // OutClass是外部类
// InnerClass是内部类

注意:

定义在class类名{}的外部的,即便在一个文件夹内,都不是内部类

public class A{
}
class B{
} // A 和 B是两个独立的类,彼此之前没有关系

内部类和外部类共用同一个Java源文件,但是经过编译后,内部类会形成单独的字节码文件

内部类的分类

根据内部类在类中位置不同,可以分为以下几种:

成员内部类:未被static修饰的实例内部类和被static修饰的静态内部类

局部内部类(不谈修饰符)

匿名内部类

public class OutClass {// 成员位置定义:未被static修饰 --->实例内部类public class InnerClass1{} // 成员位置定义:被static修饰 ---> 静态内部类static class InnerClass2{}public void method(){
// 方法中也可以定义内部类 ---> 局部内部类:几乎不用class InnerClass5{}}
}

实例内部类

未被static修饰的内部类:

public class OutClass {private int a;static int b;int c;public void methodA() {a = 10;System.out.println(a);}public static void methodB() {System.out.println(b);} //实例内部类:未被static修饰class InnerClass {int c;public void methodInner() {
// 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员a = 100;b = 200;methodA();methodB();
// 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的c = 300;System.out.println(c);
// 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字OutClass.this.c = 400;System.out.println(OutClass.this.c);}}public static void main(String[] args) {
// 外部类:对象创建 以及 成员访问OutClass outClass = new OutClass();System.out.println(outClass.a);System.out.println(OutClass.b);System.out.println(outClass.c);outClass.methodA();outClass.methodB();System.out.println("=============实例内部类的访问=============");
// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
// 创建实例内部类对象OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
// 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象OutClass.InnerClass innerClass2 = outClass.new InnerClass();innerClass2.methodInner();}
}

注意:

1. 外部类中的任何成员都可以在实力内部类中直接访问  

2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束

3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问

4. 实例内部类对象必须在先有外部类对象前提下才能创建

5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用 

6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

静态内部类

被static修饰的内部类就称为静态内部类

public class OutClass {private int a;static int b;public void methodA(){a = 10;System.out.println(a);}public static void methodB(){System.out.println(b);} // 静态内部类:被static修饰的成员内部类static class InnerClass{public void methodInner(){
// 在内部类中只能访问外部类的静态成员
// a = 100; // 编译失败,因为a不是类成员变量b =200;
// methodA(); // 编译失败,因为methodA()不是类成员方法methodB();}}public static void main(String[] args) {
// 静态内部类对象创建 & 成员访问OutClass.InnerClass innerClass = new OutClass.InnerClass();innerClass.methodInner();}
}

注意:

在静态内部类中只能访问外部类中的静态成员 

创建静态内部类对象时,不需要先创建外部类对象 

局部内部类 

定义在外部类的方法体或者{}中,这种内部类只能在其定义的位置使用,一般使用的非常少:

public class OutClass {int a = 10;public void method(){int b = 10;
// 局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰class InnerClass{public void methodInnerClass(){System.out.println(a);System.out.println(b);}} // 只能在该方法体内部使用,其他位置都不能用InnerClass innerClass = new InnerClass();innerClass.methodInnerClass();}public static void main(String[] args) {
// OutClass.InnerClass innerClass = null; 编译失败}
}

注意:

1. 局部内部类只能在所定义的方法体内部使用

2. 不能被public、static等修饰符修饰

3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class

4. 几乎不会使用 

匿名内部类 

这个内部类是没有名字的:

interface IA {void test();
}public class Test {public static void main(String[] args) {IA a = new IA() {@Overridepublic void test() {System.out.println("重写的方法");}};a.test();}


 

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

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

相关文章

Vue--1.4Vue指令

Vue会根据不同的指令&#xff0c;针对标签实现不同的功能。 指令&#xff1a;带有v-前缀的特殊标签属性 v-前缀"表达式" 1.v-html 作用:动态解析标签innerHTML <!doctype html> <html> <head><meta charset"utf-8"><meta …

计算机竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

详解初阶数据结构之顺序表(SeqList)——单文件文件实现SeqList的增删查改

目录 一、线性表 二、顺序表 2.1概念及结构 2.2接口实现 2.3动态顺序表的创建 2.3动态顺序表的初始化 2.3.1传值初始化 2.3.2传址初始化 2.4动态顺序表的清空 2.5动态顺序表的扩容 2.6动态顺序表内容的打印 三、动态顺序表的使用 3.1尾插尾删 3.1.1尾插 3.1.2尾删…

软件测试/测试开发丨ChatGPT:带你进入智能对话的新时代

简介 人工智能时代来临 我们正处于AI的iPhone时刻。——黄仁勋&#xff08;英伟达CEO&#xff09; ChatGPT 好得有点可怕了&#xff0c;我们距离危险的强人工智能不远了。——马斯克&#xff08;Tesla/SpaceX/Twitter CEO&#xff09; 以上的内容说明我们现在正处于一个技术大…

【uni-app】

准备工作 1.下载hbuilder&#xff0c;插件使用Vue3的uni-app项目 2.需要安装编译器 3.下载微信开发者工具 4.点击运行->微信开发者工具 5.打开微信开发者工具的服务端口 效果图 page.json&#xff08;添加路由&#xff0c;修改底层导航栏&#xff0c;背景色&#xff09…

读书笔记:多Transformer的双向编码器表示法(Bert)-1

多Transformer的双向编码器表示法 Bidirectional Encoder Representations from Transformers&#xff0c;即Bert&#xff1b; 本笔记主要是对谷歌Bert架构的入门学习&#xff1a; 介绍Transformer架构&#xff0c;理解编码器和解码器的工作原理&#xff1b;掌握Bert模型架构…

2023.9.7 关于 TCP / IP 的基本认知

目录 网络协议分层 TCP/IP 五层&#xff08;四层&#xff09;模型 应用层 传输层 网络层&#xff08;互联网层&#xff09; 数据链路层&#xff08;网络接口层&#xff09; 物理层 网络数据传输的基本流程 网络协议分层 为什么需要分层&#xff1f; 分层之后&#xff0c…

MATLAB实现数据插值

目录 一.理论知识 二.一维插值实例 三.二维插值实例 一.理论知识 所谓插值&#xff0c;顾名思义&#xff0c;插入数值。很多时候&#xff0c;我们仅有离散点上的数据&#xff0c;这时如果我们想要分析变量之间的函数关系&#xff0c;则无法实现。但如果通过插值处理&#xf…

PCL入门(四):kdtree简单介绍和使用

目录 1. kd树的意义2. kd树的使用 参考博客《欧式聚类&#xff08;KD-Tree&#xff09;详解&#xff0c;保姆级教程》和《(三分钟)学会kd-tree 激光SLAM点云搜索常见》 1. kd树的意义 kd树是什么&#xff1f; kd树是一种空间划分的数据结构&#xff0c;对于多个维度的数据&a…

电商(淘宝1688京东拼多多等)API接口服务:提升商业效率和用户体验的关键

电商API接口服务&#xff1a;提升商业效率和用户体验的关键 随着电子商务的飞速发展&#xff0c;电商企业需要不断提升自身的业务能力和服务质量&#xff0c;以应对日益激烈的市场竞争。为了更好地满足商家和消费者的需求&#xff0c;电商API接口服务应运而生。本文将探讨电商…

计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析

文章目录 0 前言课题背景分析方法与过程初步分析&#xff1a;总体流程&#xff1a;1.数据探索分析2.数据预处理3.构建模型 总结 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到…

jmeter调试错误大全

一、前言 在使用jmeter做接口测试的过程中大家是不是经常会遇到很多问题&#xff0c;但是无从下手&#xff0c;不知道从哪里开始找起&#xff0c;对于初学者而言这是一个非常头痛的事情。这里结合笔者的经验&#xff0c;总结出以下方法。 二、通过查看运行日志调试问题 写好…

【常用代码14】el-input输入框内判断正则,只能输入数字,过滤汉字+字母。

问题描述&#xff1a; el-input输入框&#xff0c;只能输入数字&#xff0c;但是不能显示输入框最右边的上下箭头&#xff0c; <el-input v-model"input" type"number" placeholder"请输入内容" style"width: 200px;margin: 50px 0;&…

两种解法解决LCR 008. 长度最小的子数组【C++】

文章目录 [LCR 008. 长度最小的子数组](https://leetcode.cn/problems/2VG8Kg/description/)解法暴力解法滑动窗口&#xff08;双指针法&#xff09; LCR 008. 长度最小的子数组 解法 暴力解法 //暴力解法&#xff1a; //使用双for循环依次遍历数组&#xff0c;罗列出所有情况…

华为云 异构数据迁移

数据库和应用迁移 UGO&#xff08;Database and Application Migration UGO&#xff0c;以下简称为UGO&#xff09;是专注于异构数据库结构迁移的专业服务。可将源数据库中的DDL、DML和DCL一键自动转换为华为云GaussDB/RDS的SQL语法&#xff0c;通过数据库评估、对象迁移两大核…

计算机竞赛 基于深度学习的植物识别算法 - cnn opencv python

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 MobileNetV2网络4 损失函数softmax 交叉熵4.1 softmax函数4.2 交叉熵损失函数 5 优化器SGD6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的植物识别算法 ** …

Vue3,Typescript中引用组件路径无法找到模块报错

是这么个事&#xff0c;我在vue3新创建的项目里&#xff0c;写了个组件叫headerIndex.vue&#xff0c;放到app.vue中import就会报错 路径肯定没写错&#xff0c;找到了解决方法&#xff0c;但是也没想明白为什么 解决方法如下 在vite-env.d.ts文件中加入 declare module &qu…

AJAX学习笔记6 JQuery对AJAX进行封装

AJAX学习笔记5同步与异步理解_biubiubiu0706的博客-CSDN博客 AJAX请求相关的代码都是类似的&#xff0c;有很多重复的代码&#xff0c;这些重复的代码能不能不写&#xff0c;能不能封装一个工具类。要发送ajax请求的话&#xff0c;就直接调用这个工具类中的相关函数即可。 用J…

springboot web 增加不存在的url返回200状态码 vue 打包设置

spring boot项目增加 html web页面访问 1. 首先 application.properties 文件中增加配置&#xff0c;指定静态资源目录&#xff08;包括html的存放&#xff09; spring.resources.static-locationsclasspath:/webapp/,classpath:/webapp/static/ 2. 项目目录 3. 如果有实现 …

Arm 架构 Ubuntu 使用 Docker 安装 Gitlab 并使用

官方 gitlab 文档 我的系统是 arm 架构的 ubuntu 官网没有提供 arm 架构的 docker 的 gitlab 的安装方式&#xff0c;直接安装的也是后来加的&#xff0c;文档也是随笔带过&#xff0c;&#xff0c;&#xff0c;我用到了&#xff0c;记录一下 默认已经安装了 docker 在 docker …