一文详解Object类和抽象类

作者:熬夜磕代码丶 时间:2023-06-09 16:27:14 

一、抽象类是什么?

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

一文详解Object类和抽象类

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

二、初始抽象类

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");
   }

代码可以编译通过吗?

一文详解Object类和抽象类

我们可以发现抽象类是无法实例化对象的.

2.2 继承抽象类

1.抽象方法的权限

abstract class Shape {
   abstract private void func();
}

一文详解Object类和抽象类

抽象类要被继承,需要子类实现抽象方法,所以抽象方法的权限不能是private.

注意:抽象方法没有加访问限定符时,默认是public.

abstract class Shape {
   abstract final void func();
}

一文详解Object类和抽象类

** 抽象方法不能被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();
   }

一文详解Object类和抽象类

实现父类的抽象方法后,即可正常实例化

class Rect extends Shape {
   @Override
   public void draw() {

}
}

一文详解Object类和抽象类

子类继承抽象类时,要么把抽象方法全部实现,不然将子类继续抽象化.

三、抽象类总结

  • 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 {

}

这两种是一模一样的.

一文详解Object类和抽象类

4.2 toString

Object中的toString方法:

一文详解Object类和抽象类

public static void main(String[] args) {
       Circle circle = new Circle(2);
       System.out.println(circle);
   }

一文详解Object类和抽象类

我们要打印circle对象具体内容的话,需要重写toString方法.

public String toString() {
       return "Circle{" +
               "r=" + r +
               '}';
   }

一文详解Object类和抽象类

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));
   }

一文详解Object类和抽象类

每次new一个对象都会在堆开辟一个新的空间.

一文详解Object类和抽象类

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;
   }

一文详解Object类和抽象类

比较对象中内容是否相同的时候,一定要重写equals方法。

4.4 hashcode

一文详解Object类和抽象类

我们可以发现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());
   }

一文详解Object类和抽象类

我们认为两个存储相同值的Circle对象,在调用Object的hashcode方法时,输出的值不一样.

//重写hashCode方法
@Override
   public int hashCode() {
       return Objects.hash(r);
   }

一文详解Object类和抽象类

当我们重写hashCode后,当两个对象存储的内容一样时,输出的哈希值是一样的.

结论:

  • 1、hashcode方法用来确定对象在内存中存储的位置是否相同

  • 2、事实上hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。

来源:https://blog.csdn.net/buhuisuanfa/article/details/126425103

标签:Object,类,抽象类
0
投稿

猜你喜欢

  • 浅谈Java中的n种随机数产生办法

    2023-12-22 10:36:29
  • Springboot整合FreeMarker的实现示例

    2023-04-09 00:57:57
  • Java Spring中Quartz调度器详解及实例

    2022-09-30 03:31:13
  • C#类的访问修饰符用法分析

    2021-12-22 22:23:01
  • java图形界面之布局设计

    2021-11-10 16:07:40
  • JavaScript嵌入百度地图API的最详细方法

    2023-04-12 14:33:03
  • java的多线程高并发详解

    2022-06-28 10:12:06
  • 基于WPF实现带明细的环形图表

    2021-12-01 03:58:11
  • Java常用排序算法及性能测试集合

    2022-01-15 22:29:09
  • Android 开发随手笔记之使用摄像头拍照

    2023-01-31 05:17:22
  • C#实现简单文本编辑器

    2022-04-28 06:42:30
  • 你可知HashMap为什么是线程不安全的

    2021-12-10 20:14:59
  • Spring如何解决单例bean线程不安全的问题

    2023-12-18 23:50:20
  • 完美解决java读取大文件内存溢出的问题

    2023-07-31 17:53:17
  • Java将String字符串带括号转成List的简单方法

    2022-10-26 18:20:17
  • 初识Spring Boot框架和快速入门

    2022-10-17 00:58:52
  • SpringBoot整合RabbitMQ实现消息确认机制

    2023-09-11 04:07:22
  • Android开发手册TextInputLayout样式使用示例

    2023-10-16 11:03:12
  • java开发实现五子棋游戏

    2021-09-07 12:41:32
  • JVM Client和Server端有什么区别

    2023-08-05 22:49:53
  • asp之家 软件编程 m.aspxhome.com