千字打通接口的任督二脉 | 带你学《Java面向对象编程》之五十八

简介: 本节为读者讲述了接口使用过程中遇到的转型问题以及接口与抽象类之间对于子类的继承、实现的要求。

上一篇:初识“多继承小帮手”-接口 | 带你学《Java面向对象编程》之五十七
【本节目标】
通过阅读本节内容,你将了解到使用接口时的几种转型情况与接口内访问权限的相关情况,学会正确的继承抽象类、实现接口,并能熟练处理接口对象的转型操作。

对象转型

但是这个时候我们就需要考虑一个实际的情况了,关于对象的转型问题了。

image.png
图一 对象转型

此时MessageImpl子类的对象可以任意的实现父接口的转换
范例:观察转换

interface IMessage {    //定义了一个接口
    public static final String INFO = “www.mldn.cn” ;  //全局常量
    public abstract String getInfo() ;    //抽象方法
}
interface IChannel {
    public abstract boolean connect() ;   //定义抽象方法
}
class MessageImpl implements IMessage, IChannel{    //实现了接口
    public String getInfo() {
        if(this.connect()) {
           return “得到一个消息,秘密的消息,有人胖了。”
        }
        return “通道创建失败,无法获取消息。”
    }
    public boolean connect() {
        System.out.println(“消息发送通道已经成功建立。”) ;
        return true ;
    }
}
public class JavaDemo {
    public static void main(String args[]) {
        IMessage msg = new MessageImpl() ;
        IChannel chl = (IChannel) msg ;
        System.out.println(chl.connect()) ;
    }
}

执行结果:
消息发送通道已经成功建立。
true

由于MessageImpl子类实现了IMessage与IChannel两个接口,所以这个子类可以是这两个接口任意一个接口的实例,那么就表示此时这两个接口实例之间是可以转换的。
在Java程序里面接口是不允许去继承父类的,所以说接口绝对不会是Object的子类,但是根据之前的分析可以发现,MessageImpl是Object子类,所以接口一定可以通过Object接收。
范例:观察Object与接口转换

interface IMessage {    //定义了一个接口
    public static final String INFO = “www.mldn.cn” ;  //全局常量
    public abstract String getInfo() ;    //抽象方法
}
interface IChannel {
    public abstract boolean connect() ;   //定义抽象方法
}
class MessageImpl implements IMessage, IChannel{    //实现了接口
    public String getInfo() {
        if(this.connect()) {
           return “得到一个消息,秘密的消息,有人胖了。”
        }
        return “通道创建失败,无法获取消息。”
    }
    public boolean connect() {
        System.out.println(“消息发送通道已经成功建立。”) ;
        return true ;
    }
}
public class JavaDemo {
    public static void main(String args[]) {
        IMessage msg = new MessageImpl() ;
        Object obj = msg ;     //向上转型
        IChannel chan = (IChannel) obj ;
        System.out.println(chan.connect()) ;
    }
}

执行结果:
消息发送通道已经成功建立。
true

Object类对象可以接收所有的数据类型,包括基本数据类型、类对象、接口对象、数组。
由于接口描述的是公共的定义标准,所以在接口之中所有的抽象方法的访问权限都为public,也就是说写与不写都是一样的,例如:下面的两个接口本质是完全相同的:
完整定义:

interface IMessage {    //定义了一个接口
    public static final String INFO = “www.mldn.cn” ;  
    public abstract String getInfo() ;    
}

简化定义:

interface IMessage {    //定义了一个接口
    String INFO = “www.mldn.cn” ;  
    String getInfo() ;    
}

方法不写访问权限也是public,不是default,所以覆写的时候只能够使用public。
接口虽然已经可以成功的进行定义,但是千万不要忽略,在实际的开发过程之中,实现接口的有可能是抽象类,也就是说一个抽象类可以实现多个接口,而一个普通类只能够继承一个抽象类并且可以实现多个父接口,但是要求先继承后实现。
范例:子类继承抽象类并且实现接口

interface IMessage {    //定义了一个接口
    public static final String INFO = “www.mldn.cn” ;  //全局常量
    public abstract String getInfo() ;    //抽象方法
}
interface IChannel {
    public abstract boolean connect() ;   //定义抽象方法
}
abstract class DatabaseAbstract {    //定义一个抽象类
     //接口中的abstract可以省略,抽象类中不允许省略
    public abstract boolean getDatabaseConnection() ;
}
class MessageImpl extends DatabaseAbstract implements IMessage, IChannel{    //实现了接口
    public String getInfo() {
        if(this.connect()) {
          if (this. getDatabaseConnection()) {
             return “得到一个消息,秘密的消息,有人胖了。”
          }elae {
             return “数据库消息无法访问。”
          }
        }
        return “通道创建失败,无法获取消息。”
    }
    public boolean connect() {
        System.out.println(“消息发送通道已经成功建立。”) ;
        return true ;
    }
    public boolean getDatabaseConnection() {
        return true ;
    }
}
public class JavaDemo {
    public static void main(String args[]) {
        IMessage msg = new MessageImpl() ;
        System.out.println(msg.getInfo()) ;
    }
}

执行结果:
消息发送通道已经成功建立。
得到一个消息,秘密的消息,有人胖了。

虽然接口无法去继承一个父类,但是一个接口却可以通过extends继承若干个父接口,此时称为接口的多继承。
范例:实现接口的多继承

interface IMessage {    
    public abstract String getInfo() ;    //抽象方法
}
interface IChannel {
    public boolean connect() ;
}
//extends在类继承上只能够继承一个父类,但是接口上可以继承多个
interface IService extends IMessage ,IChannel {    //接口多继承
    public String service() ;
}
class MessageService implements IService {
    public String getInfo() {
        return null ;
    }
    public boolean connect() {
        return true ;
    }
    public String service() {
        return “获取消息服务。”
    }
}

在实际的开发之中,接口的使用往往有三种形式:
进行标准设置;
表示一种操作的能力;
暴露远程方法视图,这个一般都在RPC分布式开发中使用。

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:接口的魅力:全能的世界蓝图 | 带你学《Java面向对象编程》之五十九
更多Java面向对象编程文章查看此处

相关文章
|
1天前
|
安全 Java 调度
Java一分钟:多线程编程初步:Thread类与Runnable接口
【5月更文挑战第11天】本文介绍了Java中创建线程的两种方式:继承Thread类和实现Runnable接口,并讨论了多线程编程中的常见问题,如资源浪费、线程安全、死锁和优先级问题,提出了解决策略。示例展示了线程通信的生产者-消费者模型,强调理解和掌握线程操作对编写高效并发程序的重要性。
19 3
|
1天前
|
Java API
Java 接口
5月更文挑战第6天
|
2天前
|
Java
04|零基础玩转面向对象编程:Java OOP
04|零基础玩转面向对象编程:Java OOP
5 0
|
2天前
|
存储 安全 Java
Java一分钟之-Map接口与HashMap详解
【5月更文挑战第10天】Java集合框架中的`Map`接口用于存储唯一键值对,而`HashMap`是其快速实现,基于哈希表支持高效查找、添加和删除。本文介绍了`Map`的核心方法,如`put`、`get`和`remove`,以及`HashMap`的特性:快速访问、无序和非线程安全。讨论了键的唯一性、`equals()`和`hashCode()`的正确实现以及线程安全问题。通过示例展示了基本操作和自定义键的使用,强调理解这些概念对编写健壮代码的重要性。
5 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中函数式接口
|
2天前
|
Java
【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态
【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态
|
1天前
|
Java
Java一分钟:线程协作:wait(), notify(), notifyAll()
【5月更文挑战第11天】本文介绍了Java多线程编程中的`wait()`, `notify()`, `notifyAll()`方法,它们用于线程间通信和同步。这些方法在`synchronized`代码块中使用,控制线程执行和资源访问。文章讨论了常见问题,如死锁、未捕获异常、同步使用错误及通知错误,并提供了生产者-消费者模型的示例代码,强调理解并正确使用这些方法对实现线程协作的重要性。
9 3
|
1天前
|
安全 算法 Java
Java一分钟:线程同步:synchronized关键字
【5月更文挑战第11天】Java中的`synchronized`关键字用于线程同步,防止竞态条件,确保数据一致性。本文介绍了其工作原理、常见问题及避免策略。同步方法和同步代码块是两种使用形式,需注意避免死锁、过度使用导致的性能影响以及理解锁的可重入性和升级降级机制。示例展示了同步方法和代码块的运用,以及如何避免死锁。正确使用`synchronized`是编写多线程安全代码的核心。
22 2