【Java】面向对象之——接口的理解(二)

简介: 算法

🎄接口之间的继承


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

interface IRunning { 
 void run(); 
} 
interface ISwimming { 
 void swim(); 
} 
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming { 
} 
class Frog implements IAmphibious { 
 ... 
}

通过接口继承 创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就要继续通过在Frog类中 重写实现 run 方法和 swim 方法.


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


🎄Cloneable 接口和深浅拷贝


Java 中内置了一些很有用的接口, Clonable 就是其中之一.


Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”.


但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出CloneNotSupportedException 异常.


给Player类实现Clonable 接口

public class Player implements Cloneable{
    protected String name;
    int []age=new int[1];
    public Player(String name, int age) {
        this.name = name;
        this.age[0] = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

创建一个player1对象,然后克隆一个player1

这里需要重点理解一下 深拷贝 和 浅拷贝,clone方法默认是 浅拷贝! 运行结果可以证明


public class 接口测试 {
    public static void main(String[] args)throws CloneNotSupportedException {
        Player player1 = new Player("kobe",18);
        Player player2 = (Player) player1.clone();//克隆player1
        System.out.println("克隆player1");
        System.out.println(player1);
        System.out.println(player2);
        System.out.println();
        System.out.println("player1的名字和年龄:"+player1.name+player1.age[0]);
        System.out.println("player2的名字和年龄:"+player2.name+player2.age[0]);
        System.out.println("player1和player2的名字是否相同: " + (player2.name==player1.name));
        System.out.println("player1和player2的年龄是否相同: " + (player2.age[0]==player1.age[0]));
        System.out.println();
        System.out.println("将player2的名字改为 奥尼尔 年龄改为 20");
        player2.name ="奥尼尔";//修改player2的名字
        player2.age[0] =20;//修改player2的年龄
        System.out.println("player1的名字和年龄:"+player1.name+player1.age[0]);
        System.out.println("player2的名字和年龄:"+player2.name+player2.age[0]);
    }
}

运行结果如下

5.png


代码或许不太好理解,没关系,请看下图

6.png

然后将player2的 名字 年龄 都改一下


7.png

会发现一个问题,player2的age发生了修改,player1的age同时也会变,因为他们的age引用指向的是同一个地方


但是修改了名字,为什么player1的名字还是原来的kobe,而不是变成player2的奥尼尔,这是因为,字符串常量是不能被修改的,但是字符串的引用是可以修改的,所以会在字符串常量池中新创建一个字符串 “奥尼尔”,然后引用这个新的字符串


综上所述


什么是浅拷贝?


①我们这里说的浅拷贝是指我们拷贝出来的对象内部的引用类型变量和原来对象内部引用类型变量是同一引用(指向同一对象)。如上图所示

②但是我们拷贝出来的对象和新对象不是同一对象。

③简单来说,新(拷贝产生)、旧(原对象)对象不同,但是内部如果有引用类型的变量,新、旧对象引用的都是同一引用。

什么是深拷贝?


深拷贝:全部拷贝原对象的内容,包括内存的引用类型也进行拷贝


🎄总结


抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! ).


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

8.png


相关文章
|
7天前
|
存储 安全 Java
Java面向对象最新超详细总结版!
Java面向对象最新超详细总结版!
25 7
Java面向对象最新超详细总结版!
|
1天前
|
Java 开发者
Java一分钟之-Lambda表达式与函数式接口
【5月更文挑战第12天】Java 8引入的Lambda表达式简化了函数式编程,与函数式接口结合,实现了代码高效编写。本文介绍了Lambda的基本语法,如参数列表、箭头符号和函数体,并展示了如何使用Lambda实现`Runnable`接口。函数式接口仅有一个抽象方法,可与Lambda搭配使用。`@FunctionalInterface`注解用于确保接口具有单一抽象方法。文章还讨论了常见的问题和易错点,如非函数式接口、类型冲突以及Lambda表达式的局部变量可见性,并提供了避免这些问题的策略。通过理解Lambda和函数式接口,开发者能提高代码可读性和效率。
16 4
|
1天前
|
安全 Java 调度
Java一分钟:多线程编程初步:Thread类与Runnable接口
【5月更文挑战第11天】本文介绍了Java中创建线程的两种方式:继承Thread类和实现Runnable接口,并讨论了多线程编程中的常见问题,如资源浪费、线程安全、死锁和优先级问题,提出了解决策略。示例展示了线程通信的生产者-消费者模型,强调理解和掌握线程操作对编写高效并发程序的重要性。
37 3
|
2天前
|
Java API
Java 接口
5月更文挑战第6天
|
2天前
|
存储 安全 Java
Java一分钟之-Map接口与HashMap详解
【5月更文挑战第10天】Java集合框架中的`Map`接口用于存储唯一键值对,而`HashMap`是其快速实现,基于哈希表支持高效查找、添加和删除。本文介绍了`Map`的核心方法,如`put`、`get`和`remove`,以及`HashMap`的特性:快速访问、无序和非线程安全。讨论了键的唯一性、`equals()`和`hashCode()`的正确实现以及线程安全问题。通过示例展示了基本操作和自定义键的使用,强调理解这些概念对编写健壮代码的重要性。
6 0
|
2天前
|
存储 安全 Java
Java一分钟之-集合框架进阶:Set接口与HashSet
【5月更文挑战第10天】本文介绍了Java集合框架中的`Set`接口和`HashSet`类。`Set`接口继承自`Collection`,特征是不允许重复元素,顺序不确定。`HashSet`是`Set`的实现,基于哈希表,提供快速添加、删除和查找操作,但无序且非线程安全。文章讨论了`HashSet`的特性、常见问题(如元素比较规则、非唯一性和线程安全性)以及如何避免这些问题,并提供了代码示例展示基本操作和自定义对象的使用。理解这些概念和注意事项能提升代码效率和可维护性。
9 0
|
2天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
7 0
|
2天前
|
Java
【JAVA进阶篇教学】第四篇:JDK8中函数式接口
【JAVA进阶篇教学】第四篇:JDK8中函数式接口
|
3天前
|
Java
Java一分钟之-抽象类与接口的应用场景
【5月更文挑战第9天】Java中,抽象类和接口用于实现多态和抽象。抽象类不能实例化,提供部分实现和定义模板;接口包含无实现的抽象方法,用于定义行为规范和解耦合。选择时,关注行为用接口,部分实现用抽象类。注意抽象类的`final`和`static`方法、接口冲突等问题,明确设计目标,适度抽象,遵循接口设计原则,以提高代码质量。
12 1
|
3天前
|
Java
Java一分钟之-多态性:理解重写与接口
【5月更文挑战第9天】本文介绍了Java中的多态性,主要通过方法重写和接口实现。重写允许子类根据实际类型执行不同实现,关键点包括方法签名相同、访问权限不降低以及final、static和abstract方法不可重写。接口是抽象类型,包含抽象方法,提供另一种多态性实现。常见问题包括混淆重载与重写、不理解动态绑定以及滥用接口。为避免问题,需明确重写目的、合理设计接口,并在使用多态时注意类型检查。多态性是提升代码质量和灵活性的关键。
10 1