开发者社区> 敲代码的布莱恩特> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 算法
+关注继续查看

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

🎄语法规则

🎄实现多个接口

🎄接口使用实例

🎄接口之间的继承

🎄Cloneable 接口和深浅拷贝

🎄总结

接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量.


有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。


接口(interface)是抽象方法和常量值的定义的集合。

从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。


🎄语法规则

在打印图形的示例中, 我们的父类 Shape 并没有包含别的非抽象方法, 也可以设计成一个接口

interface IShape { 
 void draw(); 
} 
class Cycle implements IShape { 
 @Override 
 public void draw() { 
 System.out.println("○"); 
 } 
} 
public class Test { 
 public static void main(String[] args) { 
 IShape shape = new Cycle(); 
 shape.draw(); 
 } 
} 

1.png


代码解释:


使用 interface 定义一个接口

接口中的方法一定是抽象方法, 因此可以省略 abstract

接口中的方法一定是 public, 因此可以省略 public

Cycle 使用 implements 继承接口. 此时表达的含义不再是 “扩展”, 而是 “实现”

在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.

接口不能单独被实例化.

扩展(extends) vs 实现(implements)

扩展指的是当前已经有一定的功能了, 进一步扩充功能.


实现指的是当前啥都没有, 需要从头构造出来.


接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static)


interface IShape { 
 void draw(); 
 public static final int num = 10; 
}

其中的 public, static, final 的关键字都可以省略.省略后的 num 仍然表示 public 的静态常量.


提示:


1.我们创建接口的时候, 接口的命名一般以大写字母 I 开头.

2.接口的命名一般使用 “形容词” 词性的单词.

3.阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性.


一个错误的代码

interface IShape { 
abstract void draw() ; // 即便不写public,也是public 
} 
class Rect implements IShape { 
void draw() { 
System.out.println("□") ; //权限更加严格了,所以无法覆写。
} 
}


技巧:接口中的 public, static, final 的关键字都可以省略.


接口中的方法一定是抽象方法, 因此可以省略 abstract

接口中的方法一定是 public, 因此可以省略 public

接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).


🎄实现多个接口


有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的.

然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果.

现在我们通过类来表示一组动物.

class Animal { 
 protected String name; 
 
 public Animal(String name) { 
 this.name = name; 
 } 
}

另外我们再提供一组接口, 分别表示 “会飞的”, “会跑的”, “会游泳的”.

interface IFlying { 
 void fly(); 
} 
interface IRunning { 
 void run(); 
} 
interface ISwimming { 
 void swim(); 
}

接下来我们创建几个具体的动物

猫, 是会跑的.

class Cat extends Animal implements IRunning { 
 public Cat(String name) { 
 super(name); 
 } 
 @Override 
 public void run() { 
 System.out.println(this.name + "会跑"); 
 } 
}


鱼, 是会游的.

class Fish extends Animal implements ISwimming { 
 public Fish(String name) { 
 super(name); 
 } 
 @Override 
 public void swim() { 
 System.out.println(this.name + "会游泳"); 
 } 
} 

青蛙, 既能跑, 又能游(两栖动物)

class Frog extends Animal implements IRunning, ISwimming { 
 public Frog(String name) { 
 super(name); 
 } 
 @Override 
 public void run() { 
 System.out.println(this.name + "会跑"); 
 } 
 @Override 
 public void swim() { 
 System.out.println(this.name + "会游泳"); 
 } 
}

天鹅,既能飞,又能跑,还会游泳(三栖动物)

class Swan extends Animal implements IRunning, ISwimming, IFlying { 
 public Swan(String name) { 
 super(name); 
 } 
 @Override 
 public void fly() { 
 System.out.println(this.name + "会飞"); 
 } 
 @Override 
 public void run() { 
 System.out.println(this.name + "会跑"); 
 } 
 @Override 
 public void swim() { 
 System.out.println(this.name + "会游泳"); 
 } 
} 

运行结果如下:

3.png


上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口(会跑,会游,会飞).


继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性 .


猫是一种动物, 具有会跑的特性.

青蛙也是一种动物, 既能跑, 也能游泳

天鹅也是一种动物, 既能跑, 也能游, 还能飞


【这样设计有什么好处呢?】

时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力.


🎄接口使用实例


实例:给对象数组排序

先给定一个学生类

class Student { 
 private String name; 
 private int score; 
 public Student(String name, int score) { 
 this.name = name; 
 this.score = score; 
 } 
 
 @Override 
 public String toString() { 
 return "[" + this.name + ":" + this.score + "]"; 
 } 
}

再给定一个学生对象数组, 对这个对象数组中的元素进行排序(按分数降序).

Student[] students = new Student[] { 
 new Student("张三", 95), 
 new Student("李四", 96), 
 new Student("王五", 97), 
 new Student("赵六", 92), 
}; 

按照我们之前的理解, 数组我们有一个现成的 sort 方法能否直接使用这个方法呢?

Arrays.sort(students); 
System.out.println(Arrays.toString(students)); 
// 运行出错, 抛出异常. 
Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to 
java.lang.Comparable 

仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定?

这时候就需要我们额外指定.


让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法

public class Student implements Comparable{

        private String name;
        private int score;
        public Student(String name, int score) {
            this.name = name;
            this.score = score;
        }

        @Override
        public String toString() {
            return "[" + this.name + ":" + this.score + "]";
        }

        @Override//重写Comparable接口里的compare To 方法
        public int compareTo(Object o) {
            Student s = (Student)o;
            if (this.score > s.score) {
                return -1;
            } else if (this.score < s.score) {
                return 1;
            } else {
                return 0;
            }
        }
}

在 sort 方法中会自动调用 compareTo 方法(具体原因可以通过ctrl+左键点击sort方法查看源码,此处不多赘叙). compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.


然后自定义 比较当前对象和参数对象的大小关系 的规则(按分数来算).


如果当前对象应排在参数对象之前, 返回小于 0 的数字;

如果当前对象应排在参数对象之后, 返回大于 0 的数字;

如果当前对象和参数对象不分先后, 返回 0;

再次执行程序, 结果就符合预期了.4.png


注意事项:

对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则.


接口就相当于是具备某种能力,在这里Comparable接口就表示具有 “可比较能力“,Student类加上(实现)了这个接口,就拥有了可比较能力,就能使用sort方法进行排序了


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【JAVA基础】面向对象基础(下)
一.构造器 二.this关键字 三.封装 四.标准 JavaBean 五.补充知识:成员变量、局部变量区别
33 0
【JAVA基础】面向对象基础(上)
一、设计对象并使用 1.定义类,创建对象并使用 2.定义类的补充注意事项 二、对象内存图 1.多个对象的内存图 2.两个变量指向同一个对象内存图 3.垃圾回收 三、面向对象编程案例 购车系统模拟
31 0
Java基础之面向对象详解
Java基础之面向对象详解
47 0
java基础之面向对象
博主简介:原互联网大厂tencent员工,网安巨头Venustech员工,阿里云开发社区专家博主,微信公众号java基础笔记优质创作者,csdn优质创作博主,创业者,知识共享者,欢迎关注,点赞,收藏。
53 0
Java SE基础知识详解第[5]期—面向对象
Java SE基础知识详解第[5]期—面向对象
654 0
Java基础——面向对象
相信大家都多多少少的听说过面向对象与面向过程的概念吧,今天阿Q就带大家一起研究一下面向对象。首先给大家说一下概念吧。面向过程其实就是在编程过程中注重步骤性,它所关心的是事件;而面向对象其实是将你所看到的事物抽象成一个对象的过程,他注重的是事物本身,也就是对象。
39 0
java基础和面向对象面试题_01
java基础和面向对象面试题_01 ============================================================================= 逻辑思考题: 1:矿泉水1元钱1瓶,每2个空瓶换一瓶矿泉水,现有20元钱,请问可以买多少瓶矿泉水? ...
1016 0
Java基础之004-面向对象
Java基础之004-面向对象                                        35岁学习Java 1.1 面向对象概念 1.1.1理解面向对象 1)     面向对象是相对面向过程而言 2)     面向对象和面向过程都是一种思想 3)     面向过程 强调的是功能行为 4)     面向对象 将功能封装进对象,强调具备了功能的对象。
918 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Java基础入门(四)-泛型、反射、注解
立即下载
JAVA反射原理以及一些常见的应用
立即下载
Java开发手册1.4.0
立即下载