一文详解Object类和抽象类
作者:熬夜磕代码丶 发布时间:2023-06-09 16:27:14
一、抽象类是什么?
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
二、初始抽象类
2.1 基本语法
在 Java 语言中使用 abstract class 来定义抽象类。
如下实例:
abstract class Employee {
//普通的成员属性
private String name;
private String address;
//构造方法
public Employee(String name, String address) {
this.name = name;
this.address = address;
}
//普通的成员方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
注意到该 Employee 类没有什么不同,尽管该类是抽象类,但是它仍然有 成员变量,成员方法和 构造方法
注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法
public static void main(String[] args) {
Employee employee = new Employee("zhangsan","shanxi");
}
代码可以编译通过吗?
我们可以发现抽象类是无法实例化对象的.
2.2 继承抽象类
1.抽象方法的权限
abstract class Shape {
abstract private void func();
}
抽象类要被继承,需要子类实现抽象方法,所以抽象方法的权限不能是private.
注意:抽象方法没有加访问限定符时,默认是public.
abstract class Shape {
abstract final void func();
}
** 抽象方法不能被final和static修饰,因为抽象方法要被子类重写**
先写一个Shape抽象类:
abstract class Shape {
//被abstract修饰的抽象方法,没有方法体
abstract public void draw();
abstract void calcArea();
}
抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰
class Circle extends Shape {
private double r;
final private static double PI = 3.14;
public Circle(double r) {
this.r = r;
}
@Override
public void draw() {
System.out.println("画圆!");
}
@Override
void calcArea() {
System.out.println("面积为: "+PI*r*r);
}
}
public static void main(String[] args) {
Circle circle = new Circle(2);
circle.draw();
circle.calcArea();
}
实现父类的抽象方法后,即可正常实例化
class Rect extends Shape {
@Override
public void draw() {
}
}
子类继承抽象类时,要么把抽象方法全部实现,不然将子类继续抽象化.
三、抽象类总结
1.抽象类中必须使用abstract修饰类
2.抽象类中可以包含普通类所能包含的成员
3.抽象类和普通类不一样的是:抽象类可以包含抽象方法.
4.抽象方法使用abstract修饰的,这个方法没有具体的实现
5.不能实例化抽象类
6.抽象类最大的意义就是被继承
7.如果一个普通类继承了一个抽象类,那么必须重写抽象类当中的方法,否则写为抽象类
8.抽象方法不能是私有的,static?也就是要满足重写的规则
9.final?不可以它和abstract是矛盾的
10.抽象类当中可以有构造方法,为了方便子类调用,来初始化类中的成员变量.
11.抽象类的出现,是为了让程序员更早的发现错误,防止出错,让编译器及时提醒我们.
四、Object类
4.1 初始Object
Java Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object 的所有方法。
Object 类位于 java.lang 包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。
class Person {
}
class Person extends Object {
}
这两种是一模一样的.
4.2 toString
Object中的toString方法:
public static void main(String[] args) {
Circle circle = new Circle(2);
System.out.println(circle);
}
我们要打印circle对象具体内容的话,需要重写toString方法.
public String toString() {
return "Circle{" +
"r=" + r +
'}';
}
4.3 equals
在Java中,进行比较时:
a.如果双等号左右两侧是基本类型变量,比较的是变量中值是否相同
b.如果双等号左右两侧是引用类型变量,比较的是引用变量地址是否相同
c.如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的:
public static void main(String[] args) {
Circle circle = new Circle(2);
Circle circle1 = new Circle(2);
int a = 1;
int b = 1;
System.out.println(a == b);
System.out.println(circle == circle1);
System.out.println(circle.equals(circle1));
}
每次new一个对象都会在堆开辟一个新的空间.
Object定义的equals方法,在两个对象调用时对比的是两个对象地址是否相等,而不是具体对象中的内容这时候我们需要重写equals方法.
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(this == obj) {
return true;
}
if(!(obj instanceof Circle)) {
return false;
}
Circle circle = (Circle)obj;
return this.r == circle.r;
}
比较对象中内容是否相同的时候,一定要重写equals方法。
4.4 hashcode
我们可以发现toString方法中有使用到这个方法,我们目前只需要知道它是一个内存地址,然后调用Integer.toHexString()方法,将这个地址以16进制输出。
public static void main(String[] args) {
Circle circle1 = new Circle(2);
Circle circle2 = new Circle(2);
System.out.println(circle1.hashCode());
System.out.println(circle2.hashCode());
}
我们认为两个存储相同值的Circle对象,在调用Object的hashcode方法时,输出的值不一样.
//重写hashCode方法
@Override
public int hashCode() {
return Objects.hash(r);
}
当我们重写hashCode后,当两个对象存储的内容一样时,输出的哈希值是一样的.
结论:
1、hashcode方法用来确定对象在内存中存储的位置是否相同
2、事实上hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。
来源:https://blog.csdn.net/buhuisuanfa/article/details/126425103


猜你喜欢
- 前言好久没写 linphone-sdk-android 相关的文章了,本文记录下笔者分析 linphone-sdk 版本号生成的过程。分析注
- 1、应用场景:从一份html文件中或从String(是html内容)中提取纯文本,去掉网页标签;2、代码一:replaceAll搞定//从h
- 在前面介绍的代码中有使用特性,这些特性都是Microsoft定义好的,作为.NET Framework类库的一部分,许多特性都得到了C#编译
- Spring Security提供如下几种认证机制Username & PasswordOAuth2.0 LoginSAML 2.0
- 本文通过实例详细阐述了C++关于智能指针的概念及用法,有助于读者加深对智能指针的理解。详情如下:一、简介由于 C++ 语言没有自动内存回收机
- ClickHouse应用场景:1.绝大多数请求都是用于读访问的2.数据需要以大批次(大于1000行)进行更新,而不是单行更新;或者根本没有更
- 在 Windows 窗体应用程序中显示图片时要使用图片控件 ( PictureBox ),图片的设置方式与背景图片的设置方式相似。图片控件中
- 序本文主要研究下迁移到java9的一些注意事项。迁移种类1、代码不模块化,先迁移到jdk9上,好利用jdk9的api2、代码同时也模块化迁移
- 最近开发过程中遇到了一个问题,之前没有太注意,这里记录一下。我用的SpringBoot版本是2.0.5,在跟前端联调的时候,有个请求因为用户
- Maven工程分模块开发完成 父工程配置了 tomcat7插件,运行 run命令执行run指令时失败,报错信息如下:D:\java\JDK8
- Android WebView常见问题解决方案汇总:就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了we
- 延伸:以后除了可以为实体类注入属性,还可以为配置类注入相关的配置信息1.编写实体类@Component@ConfigurationPrope
- 点击图标进入指定浏览器。只需在onCreate()方法里添加如下代码:String url = "http://tiger-kfp
- 本文实例讲述了C#计算程序执行过程花费时间的方法。分享给大家供大家参考。具体如下:计算执行完程序花费的时间:void AddInfo(){
- SWF Tools 是一组用来处理 Flash 的 swf 文件的工具包,包括:1. 合并工具 swfcombine2. 抽取工具 swfe
- 什么是静态单例模式?静态单例模式(Static Singleton Pattern)是我在实践中总结的模式,主要解决的问题是在预先知道某依赖
- 1、汉字转十六进制UNICODE编码字符串 /// <summary> /// //// /// <
- Android输入框实时模糊搜索很多开发场景会用到搜索框实时模糊搜索来帮助用户输入内容,如图思路是在EditText 字符变动的时候 弹出L
- 本文实例讲述了Java面向接口编程之命令模式。分享给大家供大家参考,具体如下:一 点睛某个方法需要完成某个行为,但这个行为的具体实现无法确定
- 编译Android系统APK1、设置环境export ANDROID_HOME=/home/administrator/soft/andro