接口和多态详解,还不快点学?

news2024/9/20 16:58:25

一、接口和多态基础知识

1. 抽象类

1.1 子类调用父类

现在有IDEA集成开发环境,可以给大家实时提醒哪个地方编译错误,但假如要大家用.txt文件编写程序呢。胡广问:现在这段代码错在了哪?

class Base {
    public Base(String s) {
        System.out.print("B");
    }
}

public class Derived extends Base {
    public Derived (String s) {
        System.out.print("D");
    }
    public static void main(String[] args) {
        new Derived("C");
    }
}

假如父类和子类同时拥有有参构造方法,子类的构造方法必须显性地调用父类的构造方法,否则会编译错误。所以正常的写法应该是这样。

    public Derived (String s) {
        super(s);  
        System.out.print("D");
    }

另外大家还需要注意一点,调用父类的构造方法必须在子类构造方法的第一行,调用父类的构造方法也只能出现在子类的构造方法上,否则也会是编译报错。

1.2 子类访问父类

如下代码,一共有两处编译错误。提示:错误在Child类里,能快速找出来吗?

class Parent {
    public static String staticVar = "Static Variable from Parent";
    private static String privateStaticVar = "Private Static Variable from Parent";

    public static void staticMethod() {
        System.out.println(staticVar);
    }

    private static void privateStaticMethod() {
        System.out.println(privateStaticVar);
    }
}

class Child extends Parent {
    public void staticMethod() {
        System.out.println("Static method in Child");
    }

    public void display() {
        System.out.println(staticVar);

        System.out.println(privateStaticVar);
        privateStaticMethod();
        
        staticMethod();
}

(1)父类的私有变量、私有方法,子类是有继承的,但是不能访问。所以Child.display()里的以下调用是编译错误的。

System.out.println(privateStaticVar);
privateStaticMethod();

(2)子类可以继承,同时也可以访问父类的static变量、方法。但父类的static方法大家需要注意,子类是不能直接覆盖的,所以以下代码会编译错误。

    public void staticMethod() {
        System.out.println("Static method in Child");
    }

正确的做法是为该方法添加一个static修饰符,代表这是子类的一个新方法。这种写法叫做方法隐藏,子类和父类中都有一个相同名称和参数的静态方法时,子类的方法将隐藏父类的方法。

    public static void staticMethod() {
        System.out.println("Static method in Child");
    }

另外如果父类的方法使用final修饰,子类也是不能覆盖的。

1.3 父类不可访问的方法

紧跟着上文代码的例子,父类的方法同样使用static修饰,子类的privateStaticMethod方法算不算覆盖父类的方法呢?有没有编译报错?

class Parent {
    public static String staticVar = "Static Variable from Parent";
    private static String privateStaticVar = "Private Static Variable from Parent";

    private static void privateStaticMethod() {
        System.out.println(privateStaticVar);
    }
}

class Child extends Parent {
    public void privateStaticMethod() {
        System.out.println(staticVar);
    }
}

答案是编译正常。

父类中不可访问的方法,子类编写相同名称和参数的方法并不算覆盖。父类的方法都不能访问了,也就没有覆盖这一说法了。。。

2. 接口

2.1 访问修饰符的区别

接口和抽象类有三个方面的区别,分布是类的修饰、方法的修饰、变量的修饰。我们往下看看。

(1)类

接口使用interface修饰,而抽象类使用abstract修饰。当它们作为外部类时,只能使用public、default修饰,不能使用private修饰。

(2)方法

普通接口方法只能由public abstractdefaultstatic修饰。

抽象接口方法可以由所有修饰符修饰,除了final。

总结下,它们两者也有共同点,就是都不能使用final修饰。

(3)变量

普通接口变量只能由public static final修饰。

抽象接口变量可以由所有修饰符修饰。

2.2 静态分派

这算是一个很偏的知识点了,如下代码有三个名为getType的重载方法,它们的返回类型相同、方法名也相同,只有入参类型不同。

胡广问:程序执行结果是什么?

public class Test {
    public static void main(String[] args) {
        for(Collection<?> collection: collections) {
            System.out.println(getType(collection));
        }
    }
    
    public static final Collection<?>[] collections = {new HashSet<String>(), new ArrayList<String>()};

    public static String getType(Collection<?> collection) {
        return "Super:collection";
    }
    public static String getType(List<?> list) {
        return "Super:list";
    }
    public String getType(ArrayList<?> list) {
        return "Super:arrayList";
    }
}

胡广给大家这么一行代码:Collection<?> collection = new ArrayList<Integer>()左边Collection<?>其实是静态类型,右边的new ArrayList<Integer>()其实是动态类型。

编译器在处理重载方法时,是根据参数的静态类型作为判断依据,而不是根据动态类型。collections数组里面的所有实例的静态类型都是Collection<?>getType方法也都是执行上文的第一个重载方法。

# 程序执行结果
Super:collection
Super:collection

你学会(fei)了吗?学fei之后就开始看看面试题把,看看自己是否能过关呢?

二、接口和多态常见面试题

1. 什么是 Java 接口?接口的主要用途是什么?

回答: Java 接口是一种特殊的引用数据类型,用于定义类必须实现的一组方法。接口只能包含方法的声明,而不能包含方法的实现。接口的主要用途是提供一种机制,使得不同的类可以以一致的方式进行交互。接口支持多继承,可以让类实现多个接口,提供了灵活的设计方式。

2. 接口和抽象类的区别是什么?

回答: 接口和抽象类都是用于定义规范的工具,但有以下主要区别:

  • 接口: 只能包含方法的声明(从 Java 8 起,可以有默认方法和静态方法),不能有构造函数、实例变量。一个类可以实现多个接口。
  • 抽象类: 可以包含方法的实现、构造函数和实例变量。一个类只能继承一个抽象类(Java 语言只支持单继承)。

3. Java 8 中接口有什么新特性?

回答: Java 8 引入了几个接口的新特性:

  • 默认方法: 可以在接口中定义具有默认实现的方法,使用 default 关键字。
  • 静态方法: 可以在接口中定义静态方法。
  • 函数式接口: 使用 @FunctionalInterface 注解来标记一个接口为函数式接口,确保接口只有一个抽象方法。

4. 如何在 Java 中实现多态?

回答: 多态是在 Java 中实现灵活、可扩展的对象行为的一种机制。主要有两种实现方式:

  • 方法重载: 同一个类中方法名相同但参数不同。
  • 方法重写: 子类重写父类的非静态方法。多态通过方法重写和引用类型的向上转型实现,即使用父类引用指向子类对象,可以调用子类重写的方法。

5. 什么是方法重载?方法重载和方法重写的区别是什么?

回答:

  • 方法重载: 在同一个类中,方法名相同但参数列表不同(参数类型、个数或顺序不同),且方法的返回类型可以不同。
  • 方法重写: 子类重新实现父类的已存在方法,方法名、参数列表和返回类型必须完全相同。

6. 什么是抽象方法?如何定义抽象方法?

回答: 抽象方法是没有实现的方法,只包含方法的声明。定义抽象方法时,使用 abstract 关键字,且方法体为空。抽象方法只能在抽象类或接口中定义,子类必须实现抽象方法,除非子类也是抽象类。

7. 如何使用 Java 中的接口进行回调?

回答: 接口可以用于实现回调机制。例如:

public interface Callback {
    void onComplete(String result);
}

public class Task {
    private Callback callback;

    public Task(Callback callback) {
        this.callback = callback;
    }

    public void doWork() {
        // 执行一些工作
        callback.onComplete("任务完成");
    }
}

public class Main {
    public static void main(String[] args) {
        Task task = new Task(result -> System.out.println(result));
        task.doWork();
    }
}

在这个例子中,Callback 接口用于回调机制,Task 类接受一个 Callback 实例,并在完成工作后调用 onComplete 方法。

8. 什么是接口的默认方法?你能给一个示例吗?

回答: 接口的默认方法是在接口中定义的具有默认实现的方法,使用 default 关键字。例如:

public interface MyInterface {
    default void defaultMethod() {
        System.out.println("这是一个默认方法");
    }
}

public class MyClass implements MyInterface {
    // 可以选择重写默认方法,也可以使用默认实现
}

public class Main {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.defaultMethod(); // 输出:这是一个默认方法
    }
}

9. 如果一个类实现了多个接口,其中包含相同的方法名但有不同的默认实现,如何解决冲突?

回答: 如果一个类实现了多个接口,并且这些接口有相同的方法名但不同的默认实现,编译器会报错。解决这个问题的方法是,在实现类中显式地重写这个方法,并提供一个新的实现。例如:

public interface InterfaceA {
    default void method() {
        System.out.println("InterfaceA 的实现");
    }
}

public interface InterfaceB {
    default void method() {
        System.out.println("InterfaceB 的实现");
    }
}

public class MyClass implements InterfaceA, InterfaceB {
    @Override
    public void method() {
        System.out.println("MyClass 的实现");
    }
}

10. 如何判断一个类是否实现了某个接口?

回答: 可以使用 instanceof 操作符来判断一个对象是否实现了某个接口。例如:

if (obj instanceof MyInterface) {
    // obj 实现了 MyInterface 接口
}

11. 你能解释一下“鸭子类型”在多态中的作用吗?

回答: “鸭子类型”是一种编程范式,基于对象的行为而非对象的实际类型。在 Java 中,这种类型的实现方式就是接口。如果一个对象实现了某个接口的方法,我们可以说这个对象是该接口的实现类型。通过这种方式,我们可以在不关心具体实现的情况下,利用对象的行为特性来进行编程。

12. 如何在接口中定义常量?

回答: 在接口中定义的常量使用 `public static final` 修饰符。例如: java public interface MyInterface { int CONSTANT_VALUE = 42; } 接口中的常量默认是 `public static final`,并且必须初始化。

13. Java 接口的继承和实现有什么区别?

回答: 接口的继承使用 `extends` 关键字,可以继承多个接口,并且可以继承其他接口的方法声明。而实现接口的类使用 `implements` 关键字,必须实现接口中定义的所有抽象方法。接口之间的继承是为了扩展接口的功能,而类的实现则是提供具体的实现。

14. 接口的多个继承会导致冲突吗?如何解决?

回答: 接口的多重继承不会导致问题,因为接口只定义方法的签名,不包含实现。如果多个接口中有相同的方法名但不同的默认实现,冲突会在实现类中解决。实现类需要重写这个方法,提供一个新的实现。

15. 什么是函数式接口?如何创建一个函数式接口?

回答: 函数式接口是只包含一个抽象方法的接口,可以用来作为 lambda 表达式或方法引用的目标。使用 `@FunctionalInterface` 注解来标记一个接口为函数式接口。例如: java @FunctionalInterface public interface MyFunctionalInterface { void doSomething(); } 

16. 什么是接口的多继承?这与类的多继承有何不同?

回答: 接口的多继承指的是一个接口可以继承多个接口,这种继承方式是合法的且支持的。接口之间的多继承是允许的,因为接口只定义方法签名,不包含实现。与此不同的是,Java 不支持类的多继承,以避免复杂的继承关系和潜在的冲突。

17. 在 Java 中,如何实现接口的动态代理?

回答: 可以使用 `java.lang.reflect.Proxy` 类来创建接口的动态代理。例如:

 


public interface MyInterface {
    void doSomething();
}

public class MyInvocationHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用方法:" + method.getName());
        return null;
    }
}

public class Main {
    public static void main(String[] args) {
        MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
                MyInterface.class.getClassLoader(),
                new Class[]{MyInterface.class},
                new MyInvocationHandler()
        );
        proxyInstance.doSomething();
    }
}

18. Java 中如何使用接口来实现策略模式?

回答: 策略模式是一种行为设计模式,用于定义一系列算法,并使它们可以互换。通过接口来定义这些算法,然后在上下文中使用。示例:

public interface Strategy {
    int execute(int a, int b);
}

public class AdditionStrategy implements Strategy {
    @Override
    public int execute(int a, int b) {
        return a + b;
    }
}

public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int a, int b) {
        return strategy.execute(a, b);
    }
}

public class Main {
    public static void main(String[] args) {
        Strategy strategy = new AdditionStrategy();
        Context context = new Context(strategy);
        System.out.println(context.executeStrategy(5, 3)); // 输出:8
    }
}

19. Java 接口是否支持静态方法?如何定义和使用?

回答: 是的,Java 接口支持静态方法,从 Java 8 开始,可以在接口中定义静态方法。静态方法不能被实现类重写,只能通过接口名调用。例如: 

public interface MyInterface {
    static void staticMethod() {
        System.out.println("接口的静态方法");
    }
}

public class Main {
    public static void main(String[] args) {
        MyInterface.staticMethod(); // 输出:接口的静态方法
    }
}

20. 如何在接口中定义默认方法,并让实现类选择是否重写?

回答: 默认方法在接口中使用 `default` 关键字定义,可以为接口中的方法提供默认实现。实现类可以选择是否重写默认方法。如果实现类不重写默认方法,类将使用接口提供的默认实现。例如: 

public interface MyInterface {
    default void defaultMethod() {
        System.out.println("默认实现");
    }
}

public class MyClass implements MyInterface {
    @Override
    public void defaultMethod() {
        System.out.println("重写后的实现");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.defaultMethod(); // 输出:重写后的实现
    }
}

让我们一起学习,一起进步!期待在评论区与你们见面。

祝学习愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

接口测试 —— 如何设计高效的测试用例!

摘要&#xff1a; 随着互联网应用的日益复杂化&#xff0c;接口测试已成为保证软件质量不可或缺的一部分。本文将探讨如何有效地设计接口测试用例&#xff0c;并提供实用的建议和示例。 一、引言 接口测试&#xff08;API测试&#xff09;是确保系统各部分之间交互正确性的关键…

57基于SpringBoot+Vue+uniapp的洗衣店订单管理系统的详细设计和实现(源码+lw+部署文档+讲解等)

文章目录 前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus 系统测试系统测试目的系统功能测试系统测试结论 为什么选择我代码参考数据库参考源码获取源码获取 前言 &#x1f31e;博主介绍 &#xff1a;✌全网粉丝15W,CSDN特邀作者、21…

进程间通信----管道篇

目录 一丶 无名管道 1. 特点 2. 读写特性 3. 函数接口 二丶有名管道 1.特点&#xff1a; 2.函数接口 3. 读写特性 一丶 无名管道 1. 特点 1. 只能用于具有亲缘关系的进程之间的通信 2. 半双工的通信模式&#xff0c;具有固定的读端和写端 3. 管道可以…

Qt:玩转QPainter后转之太极图

前言 简单了解了QPainter之后还是要做两个小例子练一练&#xff0c;不实际去做&#xff0c;只看看函数是没啥太大提升的&#xff0c;这里就简单画一个太极图。 正文 我们都知道太极分为阴阳鱼两部分&#xff0c;阴鱼(黑色)有个白色鱼眼&#xff0c;阳鱼(白色)有个黑色鱼眼&am…

2024最详细Maven配置教程

1、Maven 1.1、Maven简介 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以程序构建能力为特色之外&#xff0c;还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性&…

EmbeddedGUI简介

简介 文档地址&#xff1a;欢迎来到EmbeddedGUI的文档 本项目主要面对RAM资源有限&#xff08;<8KB&#xff09;&#xff0c;ROM资源有限&#xff08;<64KB&#xff0c;主要看所需字体和贴图资源&#xff09;&#xff0c;CPU资源还充裕&#xff08;<100MHz&#xff…

PDF Guru Anki - 支持 PDF 处理和 Anki 制卡的多功能工具箱

DF Guru Anki&#xff0c;这是一款能够大幅提升学习和办公效率的工具。 不仅能够帮助我们快速处理 PDF 文件&#xff0c;还能够高效管理各种学习资料&#xff0c;轻松制作 Anki 卡片。 PDF Guru Anki 支持 PDF 合并、拆分、旋转、加密等基本操作&#xff0c;还能够处理水印、书…

企业资产管理是什么?如何做好?权威指南

企业资产管理&#xff08;Enterprise Asset Management, 简称EAM&#xff09;已成为企业提升运营效率、降低维护成本、增强市场竞争力的重要手段。 本文将从企业资产管理的定义、重要性、实施方法及优化策略等方面&#xff0c;提供一份权威的指南&#xff0c;帮助企业更好地理解…

视频结构化从入门到精通——行为分析类应用

行为分析类应用 1. 认识行为分析 监控/判断视频画面中目标的运动过程、携带属性等。从数据中自动识别、跟踪和理解人类或物体行为。 1. 车的行为分析应用 车辆行为分析主要用于监控和管理车辆的动态行为&#xff0c;广泛应用于智能交通、城市管理和安全监控。关键应用包括&…

信息安全--(四)网络安全体系与安全模型(二)

其他安全模型 ■纵深防御模型&#xff1a;①安全保护②安全监测③实时响应④恢复 ■分层防护模型&#xff1a;参考OSI模型&#xff0c;对保护对象进行层次化保护。 ■等级保护模型&#xff1a;将信息系统划分成不同安全保护等级&#xff0c;采取相 应的保护措施。 ■网络生…

使用numpy快速实现统计分析的常用代码实现

文末赠免费精品编程资料~~ NumPy 是 Python 编程语言中用于数值计算的核心库之一&#xff0c;在统计分析方面&#xff0c;它也提供了各种各样的函数来实现统计分析。 NumPy统计分析功能概览 基本统计量&#xff1a;计算平均值、中位数、众数、标准差、方差等。 排序和搜索&a…

8款对比分析:哪款协同办公软件最适合您的团队?

文章介绍了以下几个工具&#xff1a;1. Worktile&#xff1b;2. PingCode&#xff1b;3. 钉钉&#xff1b;4. 有道云协作&#xff1b;5. 云之家&#xff1b;6. 飞书&#xff1b;7. 语雀&#xff1b;8. Airtable。 在当今快节奏的工作环境中&#xff0c;找到一款能够无缝同步文件…

全网最全软件测试面试题(含答案解析+文档)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计&#xff0c;到…

SPI通信(一)

1 硬件多&#xff0c;导致资源浪费&#xff08;速度快&#xff09; 1 就是分别用于发送和接收的两条线路 MOSI和MISO 2 全双工&#xff1a;MOSI(主机发送&#xff0c;从机接收) MISO(从机发送&#xff0c;主机接收) 3 支持总线挂载多设备&#xff08;一主多从&#xff09; …

初试构建工具Webpack

文章目录 一、Webpack概述二、安装Webpack三、Webpack打包实战1、创建index.js2、创建index.html3、运行webpack4、浏览index.html5、添加第二个脚本&#xff08;1&#xff09;创建index2.js&#xff08;2&#xff09;修改index.js&#xff08;3&#xff09;重新运行 webpack&a…

乱弹篇(44)涨洪水了

今&#xff08;2024年8月31日&#xff09;晨&#xff0c;笔者一如既往地骑上小型电三轮车&#xff0c;去到了寄居养老已逾六年的崇州市街子古镇味江河边遛弯健身。放眼远眺&#xff0c;啊&#xff01;涨洪水了。 照片&#xff1a;笔者手机自拍 看那刚刚修建好的&#xff0c;沿…

【C++】1326. 需要安排几位师傅加工零件

问题&#xff1a;1326. 需要安排几位师傅加工零件 类型&#xff1a;贪心 题目描述&#xff1a; 某工厂有 n 个零件加工的师傅&#xff0c;每位师傅每天能够加工出不同数量的零件。 现有 m 个零件要求一天加工完&#xff0c;请问该工厂最少需要派几个师傅来完成这次零件加工任…

兴业证券基于Apache DolphinScheduler的应用实践

文 / 兴业证券股份有限公司 刘洋 石良生 柳君 李致琪 本文来源于网络&#xff0c;如有侵权&#xff0c;请联系删除 任务调度平台&#xff0c;扮演着自动执行预设任务的重要角色&#xff0c;是业务开展过程中不可或缺的一环。随着业务规模的不断扩展&#xff0c;兴业证券每日…

物联网之硬件元器件基础知识介绍、集成电路、电阻器、电容器、电感器、二极管、三极管、晶体管、连接器、传感器、开关、电源

MENU 前言电子元件采购网址三极管持续更新中 前言 序言 硬件元器件是电子设备和系统的基本构成部分&#xff0c;它们在电子产品的设计、制造和功能实现中起着至关重要的作用。 电阻器(Resistor) 功能&#xff1a;电阻器用于限制电流流过电路的流动&#xff0c;并分配电压。它们…

【复旦微FM33 MCU 外设开发指南】外设篇3——SPI

前言 本系列基于复旦微FM33系列单片机的DataSheet编写&#xff0c;旨在提供一些开发指南。 本文章及本系列其他文章将持续更新&#xff0c;本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇 本文章最后更新日期&#xff1a;2024/08/31 文章目录 前言GPIO配置SPI配…