Java03接口与内部类

6 接口与内部类

接口 interface

对象克隆

内部类 inner class

代理 proxy

 

6.1 接口

public interface Comparable<T>
{int compareTo(T other);
}


Arrays.sort(Object[] a) 利用的是mergesort

 

接口也可以被扩展

public interface Moveable
{void move(double x, double y);
}
public interface Powered extends Moveable
{double milesPerGallon();  //public abstractdouble SPEED_LIMIT = 95; //public static final
}


标准库中的SwingConstants接口只包含NORTHSOUTHHORIZOTAL等常量,任何实现此接口的类都自动继承了这些常量。

class Employee implements Cloneable, Comparable

 

6.2 对象克隆

Objectclone()protected,默认浅拷贝。

 

实现Cloneable接口(空接口,标记用)

使用public访问修饰符重新定义clone方法

 

标记接口的唯一作用,可以使用instanceof进行类型检查

class Employ implements Cloneable
{public Employ clone() throws CloneNotSupportedException{...}
}

只要在clone中含有未实现Cloneable接口的对象,Object类的clone方法就会抛出一个CloneNotSupportException异常。

如果是final类,也可不抛异常,而是try-catch

 

6.3 接口与回调

回调(call back)是一种常见的设计模式。可以指出某个特定事件发生时应该采取的动作。

 

public interface ActionListener

{

void actionPerformed(ActionEvent event);

}

 

class TimePrinter implements ActionListener{ }

new Timer(1000, new TimePrinter()).start();  

//Timer构造器的第一个参数是发出通告的时间间隔,单位是毫秒;第二个是监听器对象,在时间到后执行actionPerformed()

 

javax.swing.JOptionPane

static void showMessageDialog(Component parent, Object message)

如果parentnull,则在中央显示

javax.swing.Timer

Timer(int interval, ActionListener listener)

void start()

void stop()

java.awt.Toolkit

void beep()

 

6.4 内部类

定义在另一个类中的类。

使用原因:

内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据

内部类可以对同一个包中的其他类隐藏起来

当想定义一个回调函数时,使用匿名内部类比较便捷

 

内部类中添加了一个外围类引用的参数 OuterClass.this

在外部类外引用公开内部类OuterClass.InnerClass

 

内部类是一种编译器现象,与虚拟机无关。

编译器将内部类翻译成用$分隔外部类名与内部类名的常规类文件,虚拟机对此一无所知

OuterClass$InnerClass

编译器为了引用外围类,生成了一个附加的实例域final OuterClass this$0

外围类将添加静态方法 static boolean access$0(OuterClass)InnerClass将调用此方法来访问外部类的私有域。

 

 

局部内部类不能用publicprivate访问说明符进行声明

它的作用域被限定在声明这个局部类的块中

优势:对外部世界可以完全隐藏起来

可以访问外部类,和被声明为final的局部变量

 

匿名内部类 anonymous inner class

InnerClass ic = new InnerClass(){ 类的实现 };

InnerClass可以是一个接口,类内实现接口方法

只创建类的一个对象

 

静态内部类

只是为了把一个类隐藏在另一个类的内部,并不需要内部类引用外围类对象

static 进行声明

 

6.5 代理

在运行时创建一个实现了一组给定接口的新类。

这种功能在编译时无法确定需要实现哪个接口时才有必要使用。

 

应用场景:

一个接口,其确切类型在编译时无法知道。

需要在程序运行状态定义一个实现这些接口的新类。

 

方案一:

生成代码,将代码放置在一个文件中,调用编译器进行编译,然后再加载结果类文件。

方案二:

代理机制,在运行时创建全新的类。这样的代理类能够实现指定接口。

指定接口有如下方法:

指定接口所需的全部方法;

Object类中的全部方法:toString equals hashcode

 

方法:

1、定义调用处理器(invocation handler),包装基本类对象。

调用处理器是实现了InvocationHandler接口的类对象。在这个接口中只用一个方法:

Object invoke( Object proxy, Method method, Object[] args)

当调用代理对象的方法时,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的调用参数,调用处理器给出处理调用的方式。

2、创建代理对象。

使用Proxy类的newProxyInstance方法,有三个参数:

一个类加载器、一个class对象数组(每个元素都是需要实现的接口)、一个调用处理器

 

例:

public interface Run
{void run();
}
public class Animal implements Run
{@Overridepublic void run(){System.out.println("Animal is running");}
}
public RunHandler implements InvocationHandler
{private Object target;public RunHandler(Object target){this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args){System.out.println("Proxy is running");return method.invoke(target, args);}
}

Animal animal = new Animal(); //基本类对象
InvocationHandler handler = new RunHandler(animal); //封装基本类对象
//handler封装的是实现Run接口的类对象。
Object proxy = Proxy.newProxyInstance(Run.class.getClassLoader(), new Class[]{Run.class}, handler);
(Run)proxy.run(); //此时代理对象proxy可以调用Run接口的方法。


代理的特性:

代理类是在运行过程中创建的,一旦被创建,就变成常规类,与虚拟机中的任何其他类没有区别。

所有代理类都扩展于Proxy类。

一个代理类只有一个实例域——调用处理器,它定义在Proxy的超类中。

为了履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器中。

 

代理类覆盖了Object类中的方法toString equals hashCode,这些方法调用了调用处理器的invoke

Object类的clonegetClass没有被重新定义。

 

没有定义代理类的名字,虚拟机中的Proxy类将生成一个以字符串$Proxy开头的类名。

对于特定类的加载器和预设的一组接口来说,只能有一个代理类。即,如果使用同一个类加载器和接口数组调用了两次newInstance方法的话,那么只能得到同一个类的两个对象。

可以用Class proxyClass = Proxy.getProxyClass(null, interfaces);

代理类一定是publicfinal

可通过Proxy类中的isProxyClass方法检测一个特定的Class对象是否代表一个代理类。

 

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

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

相关文章

第一节:ASP.NET开发环境配置

第一节&#xff1a;ASP.NET开发环境配置 什么是ASP.NET&#xff0c;学这个可以做什么&#xff0c;学习这些有什么内容&#xff1f; ASP.NET是微软公司推出的WEB开发技术。 2002年&#xff0c;推出第一个版本&#xff0c;先后推出ASP.NET2.0&#xff0c;和ASP.NET3.5&#xff0c…

深度学习笔记之win7下TensorFlow的安装

最近要学习神经网络相关的内容&#xff0c;所以需要安装TensorFlow。不得不说&#xff0c;安装TensorFlow的感受就像是大一刚入学学习C语言时&#xff0c;安装vs时一样&#xff0c;问题一大堆&#xff0c;工具都装不好&#xff0c;还学啥呀。好在&#xff0c;就在昨晚&#xff…

Java04异常、断言、日志和调试

11 异常、断言、日志和调试 异常处理&#xff08;exception handing&#xff09; 使用断言来启动检测 Java日志框架 调试技巧 11.1 处理错误 如果一个方法不能够采用正常的途径完成任务&#xff0c;就通过另外一个路径退出方法。 在这种情况下&#xff0c;方法不返回任何…

全双工与半双工的区别

1、全双工传输 (英文Full&#xff0d;Duplex &#xff09; 是指交换机在发送数据的同时也能够接收数据&#xff0c;两者同步进行&#xff0c;这好像我们平时打电话一样&#xff0c;说话的同时也能够听到对方的声音。目前的交换机都支持全双工。全双工的好处在于迟延小&#xff…

人脸识别经典算法一:特征脸方法(Eigenface)

这篇文章是撸主要介绍人脸识别经典方法的第一篇&#xff0c;后续会有其他方法更新。特征脸方法基本是将人脸识别推向真正可用的第一种方法&#xff0c;了解一下还是很有必要的。特征脸用到的理论基础PCA在另一篇博客里&#xff1a;特征脸(Eigenface)理论基础-PCA(主成分分析法)…

Java05泛型

12 泛型 12.1 为什么使用泛型 泛型程序设计&#xff08;Generic programming&#xff09;&#xff1a;意味着编写的代码可以被很多不同类型的对象所重用。 类型参数&#xff08;type parameters&#xff09; 通配符类型&#xff08;wildcard type&#xff09; 可以将Manage…

bitmap转换为drawable

Bitmap bitmap MediaStore.Images.Media.getBitmap(this, Uri.parse(string)); Drawable drawable new BitmapDrawable(bitmap);// 这样就转换成drawable格式&#xff0c;可以设置背景图片了转载于:https://www.cnblogs.com/Nigeria/p/10471028.html

numpy的下载与安装教程——(解决No module named numpy问题)

NumPy函数库是Python开发环境的一个独立模块&#xff0c;而且大多数Python发行版没有默认安装NumPy数据库&#xff0c;因此在安装Python之后必须单独安装NumPy数据库。 进入Python shell开发环境后输入 [python] view plaincopy from numpy import* 如果出现No module named …

Xception

The First ColumnThe Second Columnpadding 方式&#xff1a;same and valid The First ColumnThe Second ColumnSame 就是 增加一列相同的数 &#xff08;一般是0&#xff09;valid只保留有效的转载于:https://www.cnblogs.com/hugeng007/p/10477430.html

1.苍穹外卖-day01

苍穹外卖-day01 课程内容 软件开发整体介绍 苍穹外卖项目介绍 开发环境搭建 导入接口文档 Swagger 项目整体效果展示&#xff1a; 管理端-外卖商家使用 用户端-点餐用户使用 当我们完成该项目的学习&#xff0c;可以培养以下能力&#xff1a; 1. 软件开发整体介绍 作为一名…

7 用户和用户组

7.1 用户配置文件 7.1.1 用户信息文件 /etc/passwd man 5 passwd 查看配置文件功能 第1字段&#xff1a; 用户名称 第2字段&#xff1a; 密码标志 X代表有密码 如果用户没有密码&#xff0c;则只允许本地登录 第3字段&#xff1a; UID&#xff08;用户ID&#xff09; 0…

C#调用Python模块

编程&#xff1a;C#调用Python模块 当下&#xff0c;C#与Python都是比较热门的计算机编程语言&#xff0c;他们各有优缺点&#xff0c;如果能让他们互相配合工作&#xff0c;那是多么美好的事情&#xff0c;今天我来讲解一下如何利用C#来调用Python。 如果让C#支持调用Python模…

面试简单整理之克隆

61.为什么要使用克隆&#xff1f; 克隆获取对象的副本&#xff0c;直接用复制还是一个引用。 62.如何实现对象克隆&#xff1f; 1.被clone的类实现cloneable接口&#xff0c;重写object类的clone&#xff08;&#xff09;方法 2.如果深克隆则克隆对象的引用对象也要实现接口、重…

8 权限管理

8.1 ACL权限 8.1.1 简介与开启 用于解决身份不够用的问题 ACL(access control list) 访问控制表 ACL是存在于计算机中的一张表&#xff0c;它使操作系统明白每个用户对特定系统对象&#xff0c;例如文件目录或单个文件的存取权限。 这张表对于每个系统用户有拥有一个访问…

windows下GitHub的SSH Key 配置

https://www.jianshu.com/p/9317a927e844转载于:https://www.cnblogs.com/lishidefengchen/p/10481889.html

PyCharm调试错误

JetBrains PyCharm 2017.3.2 这就说明python.exe的环境没有配&#xff0c;点击蓝色的configure Python Interpreter&#xff0c;然后选择对应的路径就可以了

Java06集合

13 集合 实现方法时&#xff0c;不同的数据结构会导致性能有很大差异。 13.1 集合接口 Java集合类库将接口&#xff08;interface&#xff09;与实现&#xff08;implementation&#xff09;分离。 可以使用接口类型存放集合的应用&#xff0c;一旦改变了想法&#xff0c;可…

Tensorflow验证码识别应用

简单的Tensorflow验证码识别应用&#xff0c;供大家参考&#xff0c;具体内容如下 1.Tensorflow的安装方式简单,在此就不赘述了. 2.训练集训练集以及测试及如下(纯手工打造,所以数量不多): 3.实现代码部分(参考了网上的一些实现来完成的) main.py(主要的神经网络代码) ?123456…

9 文件系统管理

9.1 回顾分区和文件系统 分区类型 主分区&#xff1a;总共最多只能分四个 扩展分区&#xff1a;只能有一个&#xff0c;主分区加扩展分区最多有四个&#xff0c;必须再划分成逻辑分区才能使用。 逻辑分区&#xff1a;在扩展分区中划分的 IDE硬盘最多支持59个逻辑分区 SCSI…

Linux 桌面玩家指南:09. X Window 的奥秘

Linux 桌面玩家指南&#xff1a;09. X Window 的奥秘 原文:Linux 桌面玩家指南&#xff1a;09. X Window 的奥秘特别说明&#xff1a;要在我的随笔后写评论的小伙伴们请注意了&#xff0c;我的博客开启了 MathJax 数学公式支持&#xff0c;MathJax 使用$标记数学公式的开始和结…