一文详解Object类和抽象类

目录
  • 一、抽象类是什么?
  • 二、初始抽象类
    • 2.1 基本语法
    • 2.2 继承抽象类
  • 三、抽象类总结
  • 四、Object类
    • 4.1 初始Object
    • 4.2 toString
    • 4.3 equals
    • 4.4 hashcode

一、抽象类是什么?

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

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

二、初始抽象类

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() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。

到此这篇关于一文详解Object类和抽象类的文章就介绍到这了,更多相关Object抽象类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java中的Object类的toSpring()方法

    Object是类层次结构的根,每个类都可以将Object作为超类.所有类都直接或者间接的继承自该类 构造方法:public Object() 回想面向对象中,为什么说子类的构造方法默认访问的是父类的无参构造方法? 因为它们的顶级父类只有无参构造方法 package com.itheima_56; public class Student extends Object{ private String name; private int age; public Student(){ } public

  • PHP学习记录之面向对象(Object-oriented programming,OOP)基础【接口、抽象类、静态方法等】

    本文实例讲述了PHP面向对象(Object-oriented programming,OOP)基础.分享给大家供大家参考,具体如下: 我们可以使用接口(interface),指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容,我们可以通过 interface 关键字来定义,就像定义一个标准的类一样,但其中定义所有的方法都是空的,但是其中定义的所有方法都必须是公有,这是接口的特性. 但是我们如果要实现一个接口,就得使用 implements 操作符,并且类中必须实现接口中定义的所有方法,否

  • java中基本数据类型与Object的关系说明

    目录 基本数据类型与Object的关系 这里举一个例子 Object.基本数据类型的包装类 Object类 基本数据类型 基本数据类型与Object的关系 我知道大家是不是都听说过Object是所有类型的基类,但是这句话其实并不是正确的,因为java中基本数据类型跟Object是没有任何关系的. 这里举一个例子 这里在进行调用swap方法时,是不能直接将int类型传给swap(Object obj)方法的,因为Object其实跟基本数据类型没有一点关系,这个时候a就发现我们类型不匹配, 所以就自

  • Java Object类equals方法

    基本概念: Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入: Object类是所有Java类的祖先.每个类都使用 Object 作为超类.所有对象(包括数组)都实现这个类的方法.可以使用类型为Object的变量指向任意类型的对象 equals()方法:比较两个对象是否同一       如果两个对象具有相同的类型以及相同的属性值,则称这两个对象相等.如果两个引用对象指的是同一个对像,则称这两个变量同一.Object类中定义的equa

  • 利用feign调用返回object类型转换成实体

    目录 feign调用返回object转成实体 feign调用报类型转换错误 问题现象 排查过程 问题原因 解决办法 feign调用返回object转成实体 <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-databind</artifactId>     <version>2.9.8</version&g

  • mybatis查询返回Map<String,Object>类型的讲解

    目录 查询返回Map<String,Object>类型 mybatis返回结果为Map问题 查询返回Map<String,Object>类型 mybatis 查询返回Map<String,Object> 类型,平时没太注意怎么用,今天又遇到了总结记录一下,方便以后处理此类问题. Mapper.java中的方法: @MapKey("userId") Map<String,UserInfo> personalInfoByUserIds(Lis

  • Java的Object类九个方法技巧

    目录 一.getClass() 二.finalize() 三.toString() 四.equals()和hashcode() 五.wait().notify()和notifyAll() 六.clone() 前言: Java的Object 类的完整路径是java.lang.Object ,是所有类的父类编译,当我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类(隐式继承).Object类有九大常用方法,分别是getClass().finali

  • 一文详解Object类和抽象类

    目录 一.抽象类是什么? 二.初始抽象类 2.1 基本语法 2.2 继承抽象类 三.抽象类总结 四.Object类 4.1 初始Object 4.2 toString 4.3 equals 4.4 hashcode 一.抽象类是什么? 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用.也是因为这个原因,通常在设计阶段决

  • 一文详解Java抽象类到底有多抽象

    目录 抽象类 1.引出抽象类 2.认识抽象类 接口 1.抽象类和接口的区别 2.认识接口 3.具体实现 USB接口 接口表示能力 抽象类 1.引出抽象类 向上转型带来的最大的好处就是参数统一化,使用共同的父类引用,就可以接收所有的子类实例. 多态非常依赖方法覆写,但是子类可以选择性的覆写父类的方法,若需要强制要求子类覆写方法,就会用到抽象类其实显示生活中就有很多的抽象类,这些类都是概念化的,没法具体到某个实例,但是能描述这一类对象的共同属性和方法,比如人类,就没法具体到某一类人,世界上有很多类人

  • 一文带你搞懂Java中Object类和抽象类

    目录 一.抽象类是什么 二.初始抽象类 2.1 基本语法 2.2 继承抽象类 三.抽象类总结 四.Object类 4.1 初始Object 4.2 toString 4.3 equals 4.4 hashcode 一.抽象类是什么 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用.也是因为这个原因,通常在设计阶段决定要

  • 一文详解Java中的类加载机制

    目录 一.前言 二.类加载的时机 2.1 类加载过程 2.2 什么时候类初始化 2.3 被动引用不会初始化 三.类加载的过程 3.1 加载 3.2 验证 3.3 准备 3.4 解析 3.5 初始化 四.父类和子类初始化过程中的执行顺序 五.类加载器 5.1 类与类加载器 5.2 双亲委派模型 5.3 破坏双亲委派模型 六.Java模块化系统 一.前言 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最 终形成可以被虚拟机直接使用的Java类型,这个过程

  • 一文详解Java如何创建和销毁对象

    目录 一.介绍 二.实例构造(Instance Construction) 2.1 隐式(implicitly)构造器 2.2 无参构造器(Constructors without Arguments) 2.3 有参构造器(Constructors with Arguments) 2.4 初始化块(Initialization Blocks) 2.5 构造保障(Construction guarantee) 2.6 可见性(Visibility) 2.7 垃圾回收(Garbage collect

  • 一文详解如何用原型链的方式实现JS继承

    目录 原型链是什么 通过构造函数创建实例对象 用原型链的方式实现继承 方法1:Object.create 方法2:直接修改 [[prototype]] 方法3:使用父类的实例 总结 今天讲一道经典的原型链面试题. 原型链是什么 JavaScript 中,每当创建一个对象,都会给这个对象提供一个内置对象 [[Prototype]] .这个对象就是原型对象,[[Prototype]] 的层层嵌套就形成了原型链. 当我们访问一个对象的属性时,如果自身没有,就会通过原型链向上追溯,找到第一个存在该属性原

  • 一文详解Java拦截器与过滤器的使用

    目录 流程图 拦截器vs过滤器 SpringMVC技术架构图 项目Demo 依赖 Interceptor拦截器 Filter过滤器 1.多Filter不指定过滤顺序 2.多Filter指定过滤顺序 流程图 拦截器vs过滤器 拦截器是SpringMVC的技术 过滤器的Servlet的技术 先过过滤器,过滤器过完才到DispatcherServlet: 拦截器归属于SpringMVC,只可能拦SpringMVC的东西: 拦截器说白了就是为了增强,可以在请求前进行增强,也可以在请求后进行增强,但是不一

  • 一文详解Java线程的6种状态与生命周期

    目录 1.线程状态(生命周期) 2.操作线程状态 2.1.新创建状态(NEW) 2.2.可运行状态(RUNNABLE) 2.3.被阻塞状态(BLOCKED) 2.4.等待唤醒状态(WAITING) 2.5.计时等待状态(TIMED_WAITING) 2.6.终止(TERMINATED) 3.查看线程的6种状态 1.线程状态(生命周期) 一个线程在给定的时间点只能处于一种状态. 线程可以有如下6 种状态: New (新创建):未启动的线程: Runnable (可运行):可运行的线程,需要等待操作

  • 一文详解Java线程中的安全策略

    目录 一.不可变对象 二.线程封闭 三.线程不安全类与写法 四.线程安全-同步容器 1. ArrayList -> Vector, Stack 2. HashMap -> HashTable(Key, Value都不能为null) 3. Collections.synchronizedXXX(List.Set.Map) 五.线程安全-并发容器J.U.C 1. ArrayList -> CopyOnWriteArrayList 2.HashSet.TreeSet -> CopyOnW

  • 一文详解Python中PO模式的设计与实现

    目录 什么是PO模式 PO 三层模式 PO 设计模式的优点 将改写的脚本转为PO设计模式 构建基础的 BasePage 层 构建首页的 Page 层(HomePage) 构建登录页的 Page 层(LoginPage) 构建 首页 - 订单 - 支付 流程的 Page 层(OrderPage) PO 设计模式下测试Case的改造 在使用 Python 进行编码的时候,会使用自身自带的编码设计格式,比如说最常见的单例模式,稍微抽象一些的抽象工厂模式等等… 在利用 Python 做自动化测试的时候,

随机推荐