java之接口[通俗易懂]

java之接口[通俗易懂]java之接口1、接口的概念2、接口的属性3、接口与抽象类4、静态和私有方法5、默认方法6、解决默认方法冲突7、接口与回调1、接口的概念在java中,接口不是类,而是对符合这个接口的类的一组需求接口用interface声明声明一个Comparable接口可以将接口看成一个没有实例字段的抽象类publicinterfaceComparable{ 声明一个方法,方法的实现由实现这个接口的类来实现方法 接口绝不会有示例字段,在java8以前,在接口中绝对不会实现 方法。 priv

大家好,又见面了,我是你们的朋友全栈君。

1、接口的概念

  • 在java中,接口不是类,而是对符合这个接口的类的一组需求
  • 接口用interface声明
声明一个Comparable接口
可以将接口看成一个没有实例字段的抽象类
public interface Comparable { 
   
	声明一个方法,方法的实现由实现这个接口的类来实现方法
	接口绝不会有示例字段,在java8以前,在接口中绝对不会实现
	方法。
	private int data://error
	int compareTo();//OK
}
类实现接口
将类声明为实现某个接口用implements关键字
class Person implements Comparable { 
   
	在实现接口的类中必须实现接口中的方法,必须用public声明
	public int compareTo() { 
   
	
	}
}

2、接口的属性

  • 接口不是类,不能用new运算符来实例化一个接口
    x = new Comparable();//error
  • 虽然不可以构造接口的对象,不过可以声明接口的变量
    Comparable x;//ok
  • 接口变量只能引用实现了这个接口的类对象
  • 可以使用instanceof来检查一个对象是否实现了某个接口
    if(anObject instanceof Comparable){}
  • 虽然接口中不能由实例字段,但是可以有常量:
    int data = 10;
    这看起来并不是一个常量,但是接口中的字段总是被默认用
    public static final来修饰。
  • 一个类只能有一个超类,但是可以实现多个接口
interface Demo { 
   
    //接口中的常量并不能被实现接口的类所访问,只属于接口
    int data = 10;
    void demo();
}
interface Comparable { 
   
    int data = 12;
    void comparable();
}
class Person { 
   

}
class Student extends Person implements Comparable, Demo { 
   
    @Override
    public void comparable() { 
   
        System.out.println("实现Comparable接口中的方法");
    }
    @Override
    public void demo() { 
   
        System.out.println("实现Demo接口中的方法");
    }
}

public class App { 
   
    public static void main(String[] args) { 
   
        Student student = new Student();
        student.comparable();
        student.demo();
    }
}

3、接口与抽象类

  • 接口与抽象类的区别:
    抽象类是一种对事物的抽象,而接口是一种对行为的抽象; 抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。 抽象类是一种模板式设计,而接口是一种行为规范,是一种辐射式设计。

4、静态和私有方法

  • 在java8中,允许在接口中增加静态方法,这是合法的,但是这有违与
    接口作为抽象规范的初衷
  • 在java9中,接口的方法可以是private,private方法可以是静态方法,
    或者是实例方法。不过用法很有限。
interface Comparable { 
   
    int data = 12;
    void comparable();
    public static void print() { 
   
        System.out.println("接口中的public方法必须是静态方法");
    } 
    private void data() { 
   
        System.out.println("接口中的私有方法");
    }
}

5、默认方法

  • 可以为接口提供一个默认实现,必须用default修饰符
interface Comparable { 
   
    int data = 12;
    void comparable();
    public static void print() { 
   
        System.out.println("接口中的public方法必须是静态方法");
    }
    private void data() { 
   
        System.out.println("接口中的私有方法");
    }
    default void sleep() { 
   
        System.out.println("睡觉");
    }
}

6、解决默认方法冲突

1、超类优先;如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法
会被忽略。

interface Demo { 
   
    default void say() { 
   
        System.out.println("接口中的说话");
    }
}
class Person { 
   
    public void say() { 
   
        System.out.println("超类中的说话");
    }
}
class Student extends Person implements Demo { 
   

}
public class App { 
   
    public static void main(String[] args) { 
   
        Student student = new Student();
        student.say();
    }
}

执行结果:
在这里插入图片描述
2、接口冲突;如果一个接口提供了一个默认方法,另一个接口提供了一个
同名而且参数类型相同的方法,则实现接口的类或者这个类的超类必须覆盖这个方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当由一个接口并没有提供默认实现:
java之接口[通俗易懂]
可以看到,这种情况下也会报错,必须在实现接口的类或者其超类中
覆盖这个方法。
在这里插入图片描述

7、接口与回调

  • 回调是一种常见的程序设计模式。在这种模式中,可以指定某个特定事件发生时应该采取的动作。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Instant;

/** * TimePrinter类实现了ActionListener接口,并且实现的这个接口 * 的actionperformed方法。 * 定时器监听对象时,这个对象会调用actionperformed方法。 */
class TimePrinter implements ActionListener { 
   
    public void actionPerformed(ActionEvent event) { 
   
        System.out.println(Instant.ofEpochMilli(event.getWhen()));
        Toolkit.getDefaultToolkit().beep();
    }
}
public class App{ 
   
    public static void main(String[] args) { 
   
        TimePrinter timePrinter = new TimePrinter();
        Timer timer  = new Timer(1000, timePrinter);
        timer.start();
    }
}

8、对象克隆

先来看下面的代码及输出结果

在这里插入图片描述
可以看出person与person1引用的是同一个对象,也就是说
person = person1这样的操作并不能让person1得到person的
一个副本,而是让person1与person共同指向一个对象,那么如何
实现对象的克隆呢?答案是实现Cloneable接口,并实现clone方法。
不过Cloneable接口却没有什么关系,因为clone方法是从Object类
继承而来,所以Cloneable接口也被称为标记接口。

class Botany { 
   
    private String name;
    public void setName(String name) { 
   
        this.name = name;
    }
    public String getName(){ 
   
        return this.name;
    }
}
class Person implements Cloneable{ 
   
    private int data;

    public void setData(int data) { 
   
        this.data = data;
    }
    public int getData() { 
   
        return this.data;
    }
    public Person clone() throws CloneNotSupportedException{ 
   
        return (Person) super.clone();
    }
    Botany botany = new Botany();
}

public class Manager { 
   
    public static void main(String[] args) throws CloneNotSupportedException { 
   
       	Person person = new Person();
        Person person1 = person.clone();
        person.setData(99);
        person.botany.setName("tangxin");
        System.out.println(person.getData());
        System.out.println(person1.getData());
        System.out.println(person.botany.getName());
        System.out.println(person1.botany.getName());
    }
}

执行结果:
在这里插入图片描述

由此可见,我们的对象调用clone方法后得到的是一个不完全的副本(浅拷贝),也就是字段与方法都会完全拷贝一份,但是子对象变量任然引用同一个对象,要实现子对象的拷贝,就要在这个对象的所属的类实现Cloneable接口,并实现clone方法。

class Botany implements Cloneable{ 
   
    private String name;
    public void setName(String name) { 
   
        this.name = name;
    }
    public String getName(){ 
   
        return this.name;
    }
    public Botany clone() throws CloneNotSupportedException{ 
   
        return (Botany) super.clone();
    }
}
class Person implements Cloneable{ 
   
    private int data;

    public void setData(int data) { 
   
        this.data = data;
    }
    public int getData() { 
   
        return this.data;
    }
    public Person clone() throws CloneNotSupportedException{ 
   
        Person person = (Person)super.clone();
        person.botany = (Botany) botany.clone();
        return person;
    }
    Botany botany = new Botany();
}

public class Manager { 
   
    public static void main(String[] args) throws CloneNotSupportedException { 
   
        Person person = new Person();
        Person person1 = person.clone();
        person.setData(99);
        person.botany.setName("tangxin");
        System.out.println(person.getData());
        System.out.println(person1.getData());
        System.out.println(person.botany.getName());
        System.out.println(person1.botany.getName());
    }
}

执行结果:
在这里插入图片描述
这样得到的就是一个独立的副本(子对象没有子对象的话)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/156539.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Matlabinf_matlab中inf怎么用

    Matlabinf_matlab中inf怎么用matlab中imfinfo函数的作用

    2022年10月5日
    4
  • Webgame 设计与开发

    Webgame 设计与开发亲爱的读者,我是一名程序员,总怀着一种奢望,奢望去写本书。为什么称之为奢望呢?原因是一是经验不够丰富,二是工作紧张,时间有限,三是游戏阅历不深,四是游戏行业发展趋势不太明确,所以想写本关于游戏的书一直没有开始。近一年多来,随着对webgame的开发和理解,加上自身水平的的提高,感觉写本webgame的书时机已经成熟,关于该书的框架简单写了些,随着写作的深入,各个章节都将丰富。希望与

    2022年6月7日
    31
  • 正版office2007标准版

    正版office2007标准版正版office2007标准版正版office2007标准版,供应2007office标准版,正版office2007询价,正版office2007价格 胡辉:13590176235深圳office2007 中文家庭与学生版彩包:深圳office200

    2022年7月19日
    18
  • git提交代码流程

    git提交代码流程使用git也快有两年了,今天将常用命令总结一下,我描述一个整个的开发流程架构师在gitlab上新建了一个项目,搭好了框架1.我作为开发者之一,首先gitclonehttps://xx用idea打开项目,然后点开idea下面的console,在这里面执行git命令刚进来自然是master分支,然后我们首先创建一个自己的分支并切换过去,命令如下gitcheckout-…

    2022年6月29日
    39
  • 视频要不要开hdr_hdr在什么情况下使用

    视频要不要开hdr_hdr在什么情况下使用最近两年HDR这个概念可谓是铺天盖地而来,手机也好PC也好电视也好,都拼命往自己头上扣HDR的帽子。而在某些发烧友眼中,如果看片子不带HDR,堪比步兵变骑兵,一下子变得索然无味。然而,新事物往往也伴随着众多新坑,特别是在软硬件环境复杂的PC平台,稍有不慎就会摔得脸青鼻肿,播HDR的效果甚至不如播普通的片子。PC播HDR的大坑有几何?PC并不是专门为视频播放设计的机器,和专业的蓝光机等播放器相比…

    2022年9月14日
    0
  • mysql/mariadb 忘记root密码处理

    mysql/mariadb 忘记root密码处理

    2021年5月14日
    127

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号