【JAVA】抽象类与接口--下(二)

简介: 【JAVA】抽象类与接口--下

4. 抽象类和接口的区别


核心区别: 抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用(不必重写),而接口中不能包含普通方法,子类必须重写所有的抽象方法。



区别
抽象类(abstract) 接口(interface)
1 结构组成 普通类+抽象方法 抽象方法+全局变量
2 权限 各种权限 public
3 子类使用 使用extends关键字继承抽象类 使用implements关键字实现接口
4 关系 一个抽象类可以实现若干接口 接口不能继承抽象类,但是接口可以使用extends关键字继承多个父接口
5 子类限制 一个子类只能继承一个抽象类 一个子类可以实现多个接口


5. Object类


Object 是 Java 默认提供的一个类。Java里面除了 Object类,所有的类都是存在继承关系的。默认会继承 Object父类。即所有类的对象都可以使用 Object 的引用进行接收。


实例:使用Object接收所有类的对象


class Person{}
class Student{}
public class Test {
  public static void main(String[] args) {
    function(new Person());
    function(new Student());
  }
  public static void function(Object obj) {
    System.out.println(obj);
  }
}
//执行结果:
Person@1b6d3586
Student@4554617c

在开发之中,Object类是参数的最高统一类型。

但是Object类也存在有定义好的一些方法。如下:


e0e7db3803eb2fcb1591b14111d69b41_97414fcc7bd844ef98ce63a05993b8e4.png


5.1 获取对象信息

如果要打印对象中的内容,可以直接重写Object类中的toString()方法


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

5.2 对象比较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 Test1 {
    public static void main(String[] args) {
        Person p1 = new Person("gaobo", 20) ;
        Person p2 = new Person("gaobo", 20) ;
        int a = 10;
        int b = 10;
        System.out.println(a == b); // 输出true
        System.out.println(p1 == p2); // 输出false
        System.out.println(p1.equals(p2)); // 输出false
    }
}

Person类重写equals方法后,然后比较:


class Person{
    private String name ;
    private int age ;
    public Person(String name, int age) {
        this.age = age ;
        this.name = name ;
    }
    public 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 ;
    }
}
public class Test1 {
    public static void main(String[] args) {
        Person p1 = new Person("gaobo", 20) ;
        Person p2 = new Person("gaobo", 20) ;
        int a = 10;
        int b = 10;
        System.out.println(a == b); // 输出true
        System.out.println(p1 == p2); // 输出false
        System.out.println(p1.equals(p2)); // 输出true
    }
}

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


5.3 hashcode方法

hashcode方法源码:


public native int hashCode();
//该方法是一个native方法,底层是由C/C++代码写的。

我们认为两个名字相同,年龄相同的对象,将存储在同一个位置,如果不重写hashcode()方法,我们可以来看示例代码:


class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
public class Test1 {
    public static void main(String[] args) {
        Person per1 = new Person("gaobo", 20) ;
        Person per2 = new Person("gaobo", 20) ;
        System.out.println(per1.hashCode());
        System.out.println(per2.hashCode());
    }
}

🍤 运行结果:

a1cfc024b885a141bf7bf3c5b5859b43_4bcf5b6dcc1441228480e2af69e7c80b.png


从运行结果可以发现:两个对象的hash值是不一样的。


重写hashcode()方法:


import java.util.Objects;
//重写hashCode
class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
public class Test1 {
    public static void main(String[] args) {
        Person per1 = new Person("gaobo", 20) ;
        Person per2 = new Person("gaobo", 20) ;
        System.out.println(per1.hashCode());
        System.out.println(per2.hashCode());
    }
}

🍤 运行结果:


d4d04251768de5663d61bc82d2b53db0_f89da8db854b4df28e52253c56c041dd.png

此时,哈希值是一样。


注:


  • hashcode方法用来确定对象在内存中存储的位置是否相同
  • 事实上hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。

相关文章
|
1天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
13 6
|
1天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
【10月更文挑战第16天】Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。通过 hashCode() 和 equals() 方法实现唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 添加和遍历元素,体现了 Set 的高效性和简洁性。
11 4
|
3天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。它通过 hashCode() 和 equals() 方法确保元素唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 实现这一特性。
11 5
|
1天前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
7 2
|
3天前
|
存储 Java 数据处理
在Java集合框架中,Set接口以其独特的“不重复”特性脱颖而出
【10月更文挑战第14天】在Java集合框架中,Set接口以其独特的“不重复”特性脱颖而出。本文通过两个案例展示了Set的实用性和高效性:快速去重和高效查找。通过将列表转换为HashSet,可以轻松实现去重;而Set的contains方法则提供了快速的元素查找功能。这些特性使Set成为处理大量数据时的利器。
11 4
|
3天前
|
Java
Java Set 是一个不包含重复元素的集合接口,确保每个元素在集合中都是唯一的
【10月更文挑战第14天】Java Set 是一个不包含重复元素的集合接口,确保每个元素在集合中都是唯一的。本文介绍了 Set 的独特特性和两个常用实现类:基于哈希表的 HashSet 和基于红黑树的 TreeSet。通过示例代码展示了它们如何高效地处理唯一性约束的数据。
14 3
|
3天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其独特的“不重复性”要求,彻底改变了处理唯一性约束数据的方式。
【10月更文挑战第14天】从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其独特的“不重复性”要求,彻底改变了处理唯一性约束数据的方式。本文深入探讨Set的核心理念,并通过示例代码展示了HashSet和TreeSet的特点和应用场景。
8 2
|
3天前
|
存储 Java 索引
Java 中集合框架的常见接口和类
【10月更文挑战第13天】这些只是集合框架中的一部分常见接口和类,还有其他一些如 Queue、Deque 等接口以及相关的实现类。理解和掌握这些集合的特点和用法对于高效编程非常重要。
|
4天前
|
存储 Java 数据处理
Java中的Set接口以其独特的“不重复”特性,在集合框架中占据重要地位。
【10月更文挑战第13天】Java中的Set接口以其独特的“不重复”特性,在集合框架中占据重要地位。本文通过两个案例展示了Set的实用性和高效性:快速去重和高效查找。通过将列表转换为HashSet,可以轻松实现去重;而Set的contains方法则提供了高效的元素查找功能。这些特性使Set在处理大量数据时表现出色,值得我们在日常编程中充分利用。
16 3
|
8天前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
14 1