[core java学习笔记][第六章接口与内部类]
接口域内部类
接口
描述类具有什么功能,不给出具体实现。
内部类
用于设计协作关系的类集合
代理
实现任意接口的对象。
6.1 接口
接口声明
public interface Comparable
{
int compareTo(Object other); //接口声明中自动属于public 所以不需要public
}
接口声明不能提供的功能
- 不能含有实例域
- 不能在接口中实现方法
注意:提供实例域和方法实现的任务应该由接口实现的那个类完成
接口实现
需要完成两点
将类声明为实现给定的接口
使用
implements
这个关键词class Employee implements Comparable<Emoloyee>
对接口中的所有方法进行定义
public int compareTo(Employee other)
{
return Double.compare(salary,other.salary);
}
实现接口时必须把声明
public
具体代码见附录
常用API
java.lang.Compareable<T>
int compareTo(T other)
用这个对象与other比较,小于other返回负值,相等返回0,大于返回正值
java.util.Arrays
static void sort(Object[] a)
利用mergesort算法对数组a的元素进行排序,要求数组的类实现了Comparable接口的类
java.lang.Integer
static int compare(int x,int y)
比较x,y大小 x<y 返回负值
6.1.1 接口特性
可以使用
instanceof
判断一个对象是否有某个特定的接口if(anObject instanceof Comparable){...}
接口还能被扩展
public interface Powered extends Moveable
{
double milesPerGallon();
}
一个类可以有多个接口
class Employee implements Cloneable,Comparable
6.1.2 接口与抽象类
- 接口类似抽象类,但是Java并不支持多个抽象类,即多继承,以避免复杂;
- C++中的接口就是利用多继承完成
6.2对象克隆
对于每一个类,都需要如下三个判断
- 默认clone是否满足要求
- 默认clone是否能够通过调用可变对象的clone得到修补
- 是否不应该使用clone
如果选择1,2 必须
- 实现Cloneble 接口
- 使用public访问修饰符重新定义clone方法
在这里,Cloneable接口的出现与接口的正常使用没有任何关系。尤其是,接口并没有制定clone方法,这个方法继承自Object,接口在这里只是作为一个标记,表明类设计者知道要进行克隆处理。如果没有这个接口,会出现已检验异常(checked exception)
Cloneable接口是Java提供的几个标记接口(tagging interface)之一
使用
super.clone()
来调用Object的方法class Employee implements Cloneable
{
public Employee clone()
{
return (Employee) super.clone(); //仅仅是一个浅拷贝而已
}
}
下面是 深拷贝
clone的实例
class Employee implements Cloneable
{
...
public Employee clone() throws CloneNotSupportedException
{
// call Object.clone()
Employee cloned=(Employee) super.clone();
// clone mutable files
clone.hireDay=(Date) hireDay.clone();
}
}
必须谨慎使用clone,一旦为Employee类定义了clone方法,任何人都可以利用它克隆Manager对象。Employee的克隆方法能完成这项重任吗?很难确定。标准库只有5%实现了clone
代码见附录
6.3 接口与回调
定义
回调
(callback)是一种常见的程序设计模式,在这种模式中,可以指出某个特定事件发生时应该采取的动作。例如: 可以指出再按下鼠标或选择某个菜单项时应采取什么行动。
定时器
也是一种回调
定时器的代码见代码库
6.4 内部类
为什么要用内部类
- 内部类方法可以访问该类定义的所在的作用域的所有数据, 包括私有数据。(继承的类不行)
- 内部类可以对同一个包中的其他类隐藏。(即使定义成public也无所谓)
- 当想要定义一个回调函数且不想编写大量代码时,使用匿名(anonymous)内部类比较便捷
6.4.1 使用内部类访问对象状态
可以直接访问。
InnerClassTest见代码库。
6.4.2 内部类的特殊语法规则
OuterClass.this
表示外围内引用。
例:public void actionPerformd(ActionEvent event)
{
...
if(TalkingClock.this.beep) Toolkit.getDefaultToolkit().beep();
}
采用
outObject.new InnerClass()
来声明构造,具体见下面代码采用
OuterClass.InnerClass
在外围类的作用域之外引用内部类在OuterClass
既可以
TimerPrinter listener =new TimerPrinter();
又能
TimerPrinter listener =this.new TimerPrinter();
在main中
只能
TalkingClock clock=new TalkingClock(1000,true);
TalkingClock.TimerPrinter listener = clock.new TimerPrinter();
6.4.3 内部类是否有用,必要安全
- 内部类是一个编译器现象,与虚拟机无关。
编译器会把类翻译成用
$
分隔外部类和内部类的常规类文件,虚拟机对此一无所知。如`TalkingClock$TimerPrinter.class
内部类实际上通过一个
access$000(outer)
的方法来调用外围的私有变量- 注意如果内部类访问了私有数据域,就有可能通过附加在外围类所在包中的其他类访问它们,但做这些事情需要高超的技巧,程序员不可能无意之中就获得权限。
6.4.4 局部内部类
- 在TalkingClock示例代码中就会发现,TimePrinter这个类只在start方法中创建这个类型的对象时使用了一次,在这种情况下可以使用局部内部类。
对外部世界完全隐藏
public void start()
{
class TimerPrinter implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
int a=interval;
Date now = new Date();
System.out.println("At the tone,the time is "+now);
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
ActionListener listener =new TimerPrinter();
Timer t=new Timer(interval,listener);
t.start();
}
6.4.5 由外部方法访问final变量
- 内部类只能访问final局部变量
- 如果想要更新,使用一维final数组
- 这种用法以后慢慢细细思考 很复杂的样子
6.4.6 匿名内部类
假如只创建这个类的一个对象,就不必命名了。这种类被称为匿名内部类(anonymous inner class)
public void start(int interval,final boolean beep)
{
ActionListener listener =new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int a=interval;
Date now = new Date();
System.out.println("At the tone,the time is "+now);
if(beep) Toolkit.getDefaultToolkit().beep();
}
}
Timer t=new Timer(interval,listener);
t.start();
}
通常的语法格式是
new SuperType(construction parameters)
{
inner class methods and data
}
还能够重载方法//实质是继承了后覆盖
for(int i=0;i<dates.length;i++)
dates[i]=new Date()
{
public int compareTo(Date other)
{
counter[0]++;
return super.compareTo(other)
}
};
双括号初始化
invite(new ArrayList<String>() {{add("Harry");add("Tony");}})
注意这里的括号,外括号建立了ArrayList的一个匿名子类。内层括号则是一个对象构造块
不常用: 在静态方法,知道当前类名
new Object(){}.getClass().getEnclosingClass()
6.4.7 静态内部类
有时候使用内部类只是为了把一个类隐藏到另一个类的内部。并不需要内部类引用外围类对象。为此可以将内部类声明为static,以便取消引用
Class ArrayAlg
{
public static class Pair
{
...
}
}
6.5 代理
有点难以后补
[core java学习笔记][第六章接口与内部类]的更多相关文章
- Java 学习笔记 ------第六章 继承与多态
本章学习目标: 了解继承的目的 了解继承与多态的关系 知道如何重新定义方法 认识java.lang.object 简介垃圾回收机制 一.继承 继承是java面向对象编程技术的一块基石,因为它允许创建分 ...
- [core java学习笔记][第十一章异常断言日志调试]
第11章 异常,断言,日志,调试 处理错误 捕获异常 使用异常机制的技巧 使用断言 日志 测试技巧 GUI程序排错技巧 使用调试器 11.1 处理错误 11.1.1异常分类 都继承自Throwable ...
- [core java学习笔记][第四章对象与类]
4.3 用户自定义类 4.3.1 类数组的声明 需要两次new Employee[]=staff=new Employedd[3]; staff[0]=new Employedd(参数列表); sta ...
- [core Java学习笔记][第一二三章基本语法]
基本语法 1 Java 简单的类型 1.1 一些常量 正无穷大 Double.POSITVE_INFINITY 负无穷大 Double.NEGATIVE_INFINITY 不存在 Double.NaN ...
- [core java学习笔记][第五章继承]
5.1 类.超类和子类 定义 class Manager extends Employee { 添加方法和域 } 权限 派生类不能使用基类的私有变量 派生类调用基类的方法 利用super这个关键词 s ...
- JVM学习笔记-第六章-类文件结构
JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
sql server 关于表中只增标识问题 由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...
- 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试
20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ...
- Core Java 学习笔记——1.术语/环境配置/Eclipse汉化字体快捷键/API文档
今天起开始学习Java,学习用书为Core Java.之前有过C的经验.准备把自己学习这一本书时的各种想法,不易理解的,重要的都记录下来.希望以后回顾起来能温故知新吧.也希望自己能够坚持把自己学习这本 ...
随机推荐
- 转载--DEV GridControl 的一些基本操作
1. 如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 2. 如何新增一条记录 (1).gridView.Ad ...
- IP地址变动后,https://localhost:1158/em无法访问解决办法
一.解决的方法:重新配置em 二.步骤: 1.在 dos命令下输入 emca –repos drop 注意:监听端口号是一般是1521,特殊情况要在配置文件中找 2.成功删除资料档案库后,在dos下再 ...
- 关于DIPS的MVC 4.0项目发布与在IIS 7.0上的部署的方法
本人技术笨拙,今天在发布DIPS的MVC4.0项目,并部署到IIS上,遇到各种问题.在查询相关资料后,最终得以解决,所以想把这个过程记录下来. 首先是MVC4.0项目的发布: 打开你的VS2012网站 ...
- hdu Repositoryti
算法:字典树 题意:给你一些字符串,然后会有一些询问,输出询问在给定的字符串中出现了多少次(字串也是): 例如 add,子串有:a ,d,d,ad ,dd,add:你会发现子串d出现了两次,那么怎么办 ...
- 【JAVA编码专题】深入分析 Java 中的中文编码问题
http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/ 几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是为什么 ...
- JQuery实现倒计时效果
首先:引入jquery文件 <script type="text/javascript" src="http://www.cnblogs.com/Content/P ...
- 转载: js jquery 获取当前页面的url,获取frameset中指定的页面的url(有修改)
转载网址:http://blog.csdn.net/bestlxm/article/details/6800077 js jquery 怎么获取当前页面的url,获取frameset中指定的页面的ur ...
- java 编码转换
在网络中爬取到的数据,编码可能与当前编译器的编码不相同,而导致可能产生显示乱码的问题.那么如何将网络的编码,转换为当前编译器认可的编码(一般为UTF-8),就是个问题了. 主要使用了两个方法: Str ...
- python学习第四天 --字符编码 与格式化及其字符串切片
字符编码 与格式化 第三天已经知道了字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采 ...
- Core Data入门-备用
简介 Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象. ...