【Java SE】抽象类和接口(下)

简介: 首先来看到抽象这两个字,抽象其实是与具体对应的概念,在我们面向对象的概念中,所有的对象都是由类来描述的,如果我们反过来呢?

2.5 实现多个接口

在类的学习中,我们学到Java中的类是不能多继承的,但是一个类可以实现多个接口,就拿我们之前的动物类来说,我有一个猫,他是动物,他既能跑但是不会游泳,但是青蛙,也是动物,他既能跑又会游泳,我们该如何用代码表示呢?

interface IRun {
    void run();
}
interface ISwimming {
    void swimming();
}
public class Animal {
    private String name;
    public Animal() {} //构造方法
    public Animal(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
class Cat extends Animal implements IRun {
    public Cat() {} //构造方法
    public Cat(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(super.getName() + "正在跑!");
    }
}
class Frog extends Animal implements IRun, ISwimming {
    public Frog() {} //构造方法
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(super.getName() + "正在跑!");
    }
    @Override
    public void swimming() {
        System.out.println(super.getName() + "正在游泳!");
    }
}
class Test {
    public static void running(IRun r) {
        r.run();
    }
    public static void swimming(ISwimming s) {
        s.swimming();
    }
    public static void main(String[] args) {
        new Cat("小猫").run();
        Frog frog = new Frog("青蛙");
        frog.run();
        frog.swimming();
    }
}

如上代码就是Java面向对象最常见的:一个类继承了一个类实现了多种接口,当然这里我们只是很简单的演示一下,像上面也就是说,青蛙既能跑又能游泳,所以实现了跑和游泳的接口,接着我们自己在外部实现一个对应行为的方法比如 running 方法,这样一来,我们就不去关心类型,只用关心某个类能否具备某种能力(是否实现了对应接口),甚至你添加一个机器人类,实现跑的接口,仍然可以放到 running 这个方法中一样能跑,因为我们只关心机器人具不具备跑的能力,而不去关心他机器人的类型是什么!

2.6 接口之间的继承

学习类我们之类,Java中的类不支持多继承,但是一个类可以实现多个接口,而接口与接口之间可以达到多继承的目的。

接口可以继承另一个接口,达到复用的效果,使用 extends 关键字:

interface IRunning {
    void run();
}
interface ISwimming {
    void swimming();
}
//两栖动物,既能跑也能游泳,还能吃饭
interface IAmphibious extends IRunning, ISwimming {
    void eat();
}
class Frog implements IAmphibious {
    //...code 需要实现IRunning,ISwimming,IAmphibious方法
}

接口之间的继承相当于把多个接口合并在一起。

2.7 抽象类和接口的区别

这个也是面试可能会问到一道题,那么抽象类和接口有什么区别呢?

从结构组成来看:抽象类是由普通类加抽象方法构成的,而接口是由抽象方法加全局变量构成的。

从关系上来看:一个抽象类可以实现若干个接口,接口不能继承抽象类, 但可以使用 extends 继承多个父类接口

从子类限制来看:一个子类只能继承一个抽象类,一个子类可以实现多个接口。

核心区别:抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用(不用重写),而接口中不能包含普通方法(default,static修饰除外),子类必须重写所有的抽象方法。抽象类的存在是为了让编译器更好的校验!

3、Object 类

3.1 认识Object类

这个类其实每个人都用过,但是对于初学者可能没发现,Object 是Java默认提供的一个类,Java中除了 Object 类,所有的类都是存在继承关系,也就是说,都会默认继承 Object 类,即所有对象的都可以使用 Object 的引用来接收,例如:

class Student {}
class Teacher {}
public class TestDemo {
    public static void function(Object o) {
        System.out.println(o);
    }
    public static void main(String[] args) {
        function(new Student());
        function(new Teacher());
    }
}

打印结果:

Student@1b6d3586

Teacher@4554617c

当然Objcet类中里面也有许多方法,后期我们会随着学习的深入,都会学习到,而本期我们就简单的了解两个方法:toString,equals 方法

3.2 获取对象信息 toString

不知道在打印数组的时候我们使用 Arrays.toString(array),就可以将array数组转换成字符串返回,我们来简单看下 Object 类中 toString 的实现方法:

这里小伙伴就纳闷了,这行代码为何能将数组转换成字符串呢?错了错了!看清楚,是Arrays类里面的toString是将数组转换成字符串返回的,为什么 Arrays 类里面的可以实现?因为除 Object 类之外所有类都默认继承了 Object 类,也就是可以重写 Object 类中的方法, 也即 Arrays 类中重写的 toString 方法:

所以如果我们要将对象信息转换成字符串,在没有重写 toString 方法的前提下,也就会打印像我们上面举例的代码一样,打印出:Student@1b6d3586 类似这种东西,那我们就来重写下 toString:

class Student {
    private String name;
    private int age;
    private double score;
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student student = new Student("李四", 15, 83);
        String ret = student.toString();
        System.out.println(ret);
        System.out.println(new Student("张三", 12, 59.9).toString());
    }
}

当然这个重写是我自己用编译器生成的,如果你是 IDEA 可以在要重写的类中右击选择 Generat -> toString(),可以根据情况选择内容,然后确认即可,当然生成之后你也可以做修改。

上面代码第一种打印方法,是把 toString 的返回的字符串给了一个字符串引用,在通过打印方法进行打印,而第二种则是 new 了一个匿名对象直接访问重写的 toString方法,然后配合打印方法进行打印,当然匿名对象会在后续学习。

3.3 对象的比较 equals

在Java中使用 == 号比较的话,如果左右两侧是基本类型,比较的是变量中的值是否相同,但如果左右两边是引用类型,则比较引用变量的地址是否相同,因为引用变量中存的就是地址!

显然我们要比较对象的大小肯定是要重写的,我们可以先来看下 Object 类中的 equals 方法:

那我们要比较对象的大小,对象中又有这么多的成员变量,肯定是需要挑一个属性作为比较的,所以我们就选择 age 作为比较:

class Student {
    private String name;
    private int age;
    private double score;
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true; //当前对象引用的地址是否等于要比较对象的地址
        }
        //如果不是Student类对象
        if (!(o instanceof Student)) {
            return false;
        }
        //使用age作比较 注意:因为o是Object类型,向下转型才能访问Student类的属性
        return (this.age == ((Student) o).age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student student1 = new Student("李四", 15, 83);
        Student student2 = new Student("张三", 20, 59.9);
        if (student1.equals(student2)) {
            System.out.println("student1 > student2");
        } else {
            System.out.println("student1 < student2");
        }
    }
}

那么我们重写的 equals 就是按照年龄进行比较的, 如果 student1的 age 等于 student2的 age 我们就返回 true 否则返回 false,当然我们也可以按照姓名来比较,使用 this.name.equals 这个 equals就行,因为String类型本身就是引用类型,他里面也重写了 equals,至于如何操作,就交给你们啦!

相关文章
|
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 实现这一特性。
12 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成为处理大量数据时的利器。
12 4
|
3天前
|
Java
Java Set 是一个不包含重复元素的集合接口,确保每个元素在集合中都是唯一的
【10月更文挑战第14天】Java Set 是一个不包含重复元素的集合接口,确保每个元素在集合中都是唯一的。本文介绍了 Set 的独特特性和两个常用实现类:基于哈希表的 HashSet 和基于红黑树的 TreeSet。通过示例代码展示了它们如何高效地处理唯一性约束的数据。
15 3
|
3天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其独特的“不重复性”要求,彻底改变了处理唯一性约束数据的方式。
【10月更文挑战第14天】从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其独特的“不重复性”要求,彻底改变了处理唯一性约束数据的方式。本文深入探讨Set的核心理念,并通过示例代码展示了HashSet和TreeSet的特点和应用场景。
9 2
|
3天前
|
存储 Java 索引
Java 中集合框架的常见接口和类
【10月更文挑战第13天】这些只是集合框架中的一部分常见接口和类,还有其他一些如 Queue、Deque 等接口以及相关的实现类。理解和掌握这些集合的特点和用法对于高效编程非常重要。
|
4天前
|
存储 Java 数据处理
Java中的Set接口以其独特的“不重复”特性,在集合框架中占据重要地位。
【10月更文挑战第13天】Java中的Set接口以其独特的“不重复”特性,在集合框架中占据重要地位。本文通过两个案例展示了Set的实用性和高效性:快速去重和高效查找。通过将列表转换为HashSet,可以轻松实现去重;而Set的contains方法则提供了高效的元素查找功能。这些特性使Set在处理大量数据时表现出色,值得我们在日常编程中充分利用。
17 3
|
7天前
|
Java 数据处理 开发者
Java Http 接口对接太繁琐?试试 UniHttp 框架~
【10月更文挑战第10天】在企业级项目开发中,HTTP接口对接是一项常见且重要的任务。传统的编程式HTTP客户端(如HttpClient、Okhttp)虽然功能强大,但往往需要编写大量冗长且复杂的代码,这对于项目的可维护性和可读性都是一个挑战。幸运的是,UniHttp框架的出现为这一问题提供了优雅的解决方案。
13 0